Skip to content
Snippets Groups Projects
Commit d75bfa5b authored by g0dil's avatar g0dil
Browse files

PPI: Add support for multiple notify sources per notify target

PPI: Add boolean test for debug modules
parent d27f0d17
No related branches found
No related tags found
No related merge requests found
......@@ -39,6 +39,23 @@
////////////////////////////////////////
// private members
prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
{
if (throttled() && !nativeThrottled_) {
Routes::const_iterator i (routes_.begin());
Routes::const_iterator const i_end (routes_.end());
for (; i != i_end; ++i)
if ((*i)->throttled())
break;
if (i == i_end) {
remoteThrottled_ = false;
emitUnthrottle();
}
}
else
remoteThrottled_ = false;
}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
......
......@@ -134,16 +134,6 @@ prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
remoteThrottled_ = true;
}
prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
{
if (throttled() && !nativeThrottled_) {
remoteThrottled_ = false;
emitUnthrottle();
}
else
remoteThrottled_ = false;
}
prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
{
peer().notifyThrottle();
......@@ -158,6 +148,11 @@ prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
{}
prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
{
routes_.push_back(&route);
}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
......@@ -177,6 +172,12 @@ prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle()
unthrottleCallback_ = Callback();
}
prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
const
{
return peer().throttled();
}
////////////////////////////////////////
// protected members
......
......@@ -144,12 +144,18 @@ namespace connector {
// Called after unthrottling the connector
virtual void v_unthrottleEvent();
// called by ForwardingRoute to register a new route
void registerRoute(ForwardingRoute & route);
typedef detail::Callback<>::type Callback;
Callback callback_;
bool remoteThrottled_;
bool nativeThrottled_;
typedef std::vector<ForwardingRoute*> Routes;
Routes routes_;
friend class senf::ppi::ForwardingRoute;
};
......@@ -194,6 +200,8 @@ namespace connector {
notifications. */
void onUnthrottle();
bool throttled() const;
PassiveConnector & peer() const;
protected:
......
......@@ -41,6 +41,12 @@ prefix_ void senf::ppi::module::debug::ActivePacketSource::submit(Packet packet)
output(packet);
}
prefix_ bool senf::ppi::module::debug::ActivePacketSource::boolean_test()
const
{
return output;
}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::debug::PassivePacketSource
......@@ -97,6 +103,12 @@ prefix_ senf::Packet senf::ppi::module::debug::ActivePacketSink::request()
return input();
}
prefix_ bool senf::ppi::module::debug::ActivePacketSink::boolean_test()
const
{
return input;
}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::debug::PassivePacketSink
......
......@@ -28,6 +28,7 @@
// Custom includes
#include <deque>
#include "Utils/SafeBool.hh"
#include "Packets/Packets.hh"
#include "Module.hh"
......@@ -40,7 +41,8 @@ namespace module {
namespace debug {
class ActivePacketSource
: public Module
: public Module,
public SafeBool<ActivePacketSource>
{
public:
connector::ActiveOutput output;
......@@ -48,6 +50,8 @@ namespace debug {
ActivePacketSource();
void submit(Packet packet);
bool boolean_test() const;
};
class PassivePacketSource
......@@ -75,7 +79,8 @@ namespace debug {
};
class ActivePacketSink
: public Module
: public Module,
public SafeBool<ActivePacketSink>
{
public:
connector::ActiveInput input;
......@@ -83,6 +88,8 @@ namespace debug {
ActivePacketSink();
Packet request();
bool boolean_test() const;
};
class PassivePacketSink
......
// $Id$
//
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief Events non-inline non-template implementation */
#include "Events.hh"
#include "Events.ih"
// Custom includes
#include "Route.hh"
//#include "Events.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::ppi::EventDescriptor
prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle()
{
Routes::const_iterator i (routes_.begin());
Routes::const_iterator const i_end (routes_.end());
for (; i != i_end; ++i)
if ((*i)->throttled())
break;
if (i == i_end)
enabled(true);
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "Events.mpp"
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
......@@ -65,12 +65,11 @@ prefix_ void senf::ppi::EventDescriptor::notifyThrottle()
enabled(false);
}
prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle()
prefix_ void senf::ppi::EventDescriptor::registerRoute(ForwardingRoute & route)
{
enabled(true);
routes_.push_back(&route);
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
......
......@@ -25,6 +25,7 @@
#define HH_Events_ 1
// Custom includes
#include <vector>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "predecl.hh"
......@@ -67,8 +68,13 @@ namespace ppi {
void notifyThrottle();
void notifyUnthrottle();
void registerRoute(ForwardingRoute & route);
bool enabled_;
typedef std::vector<ForwardingRoute*> Routes;
Routes routes_;
friend class ForwardingRoute;
};
......
......@@ -47,6 +47,7 @@ prefix_ senf::ppi::RouteBase::RouteBase(module::Module & module)
// senf::ppi::ForwardingRoute
prefix_ bool senf::ppi::ForwardingRoute::autoThrottling()
const
{
return autoThrottling_;
}
......@@ -56,6 +57,12 @@ prefix_ void senf::ppi::ForwardingRoute::autoThrottling(bool state)
autoThrottling_ = state;
}
prefix_ bool senf::ppi::ForwardingRoute::throttled()
const
{
return v_throttled();
}
////////////////////////////////////////
// protected members
......@@ -63,11 +70,6 @@ prefix_ senf::ppi::ForwardingRoute::ForwardingRoute(module::Module & module)
: RouteBase(module), autoThrottling_(true)
{}
prefix_ void senf::ppi::ForwardingRoute::registerRoute(connector::ActiveConnector & connector)
{
connector.registerRoute(*this);
}
////////////////////////////////////////
// private members
......
......@@ -55,6 +55,15 @@ senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::v_notifyUnthrot
}
}
template <class Source, class Target>
prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::v_throttled()
const
{
return this->autoThrottling() && (
throttled(this->source(),boost::mpl::bool_<RoutingTraits<Source>::notifySource>()) ||
throttled(this->target(),boost::mpl::bool_<RoutingTraits<Target>::notifySource>()) );
}
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
......
......@@ -45,6 +45,12 @@ prefix_ senf::ppi::Route<Source,Target>::Route(module::Module & module, Source &
////////////////////////////////////////
// protected members
template <class T>
prefix_ void senf::ppi::ForwardingRoute::registerRoute(T & ob)
{
ob.registerRoute(*this);
}
template <class T>
prefix_ void senf::ppi::ForwardingRoute::notifyThrottle(T & ob)
{
......@@ -62,12 +68,14 @@ prefix_ void senf::ppi::ForwardingRoute::notifyUnthrottle(T & ob)
template <class Source, class Target, class Base>
prefix_ Source & senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::source()
const
{
return *source_;
}
template <class Source, class Target, class Base>
prefix_ Target & senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::target()
const
{
return *target_;
}
......@@ -93,8 +101,8 @@ senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
ForwardingRouteImplementation(module::Module & module, Source & source, Target & target)
: Base(module,source,target)
{
registerRoute(source, boost::mpl::bool_<RoutingTraits<Source>::notifySource>());
registerRoute(target, boost::mpl::bool_<RoutingTraits<Target>::notifySource>());
registerRoute(source);
registerRoute(target);
}
////////////////////////////////////////
......@@ -103,44 +111,48 @@ ForwardingRouteImplementation(module::Module & module, Source & source, Target &
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
registerRoute(T & ob, boost::mpl::bool_<true> const &)
notifyThrottle(T & ob, boost::mpl::bool_<true> const &)
{
ForwardingRoute::registerRoute(ob);
ForwardingRoute::notifyThrottle(ob);
}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
registerRoute(T & ob, boost::mpl::bool_<false> const &)
notifyThrottle(T & ob, boost::mpl::bool_<false> const &)
{}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
notifyThrottle(T & ob, boost::mpl::bool_<true> const &)
notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &)
{
ForwardingRoute::notifyThrottle(ob);
ForwardingRoute::notifyUnthrottle(ob);
}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
notifyThrottle(T & ob, boost::mpl::bool_<false> const &)
notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &)
{}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &)
prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
throttled(T & ob, boost::mpl::bool_<true> const &)
const
{
ForwardingRoute::notifyUnthrottle(ob);
return ob.throttled();
}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &)
{}
prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
throttled(T & ob, boost::mpl::bool_<false> const &)
const
{
return false;
}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::detail::RouteImplementation2<Source,Target>
......
......@@ -50,7 +50,7 @@ namespace ppi {
: public RouteBase
{
public:
bool autoThrottling();
bool autoThrottling() const;
void autoThrottling(bool state); ///< Change automatic throttle notification forwarding
/**< By default, throttle notifications are automatically
forwarded from active to passive connectors. This may
......@@ -65,12 +65,14 @@ namespace ppi {
comes in. Respective for unthrottle notifications.
\param[in] state New throttle forwarding state */
bool throttled() const;
protected:
ForwardingRoute(module::Module & module);
// Called to register this route with the connectors forwarding information base
void registerRoute(connector::ActiveConnector & connector);
template <class T> void registerRoute(T & ob);
template <class T> void notifyThrottle(T & ob);
template <class T> void notifyUnthrottle(T & ob);
......@@ -83,6 +85,7 @@ namespace ppi {
// Implemented in the derived classes to forward throttling notifications
virtual void v_notifyThrottle() = 0;
virtual void v_notifyUnthrottle() = 0;
virtual bool v_throttled() const = 0;
bool autoThrottling_;
......
......@@ -97,8 +97,8 @@ namespace detail {
typedef Source source_type;
typedef Target target_type;
Source & source();
Target & target();
Source & source() const;
Target & target() const;
protected:
BaseRouteImplementation(module::Module & module, Source & source, Target & target);
......@@ -131,18 +131,18 @@ namespace detail {
ForwardingRouteImplementation(module::Module & module, Source & source, Target & target);
private:
// register the Route in the notifySource only if the second argument is a 'true' type
template <class T> void registerRoute(T & ob, boost::mpl::bool_<true> const &);
template <class T> void registerRoute(T & ob, boost::mpl::bool_<false> const &);
// send a throttle/unthrottle notification only if the second argument is a 'true' type
template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<true> const &);
template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<false> const &);
template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &);
template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &);
template <class T> bool throttled(T & ob, boost::mpl::bool_<true> const &) const;
template <class T> bool throttled(T & ob, boost::mpl::bool_<false> const &) const;
virtual void v_notifyThrottle();
virtual void v_notifyUnthrottle();
virtual bool v_throttled() const;
};
// This helper class finds the base-class suitable for a specific route. Routes are classified
......
......@@ -131,14 +131,13 @@ BOOST_AUTO_UNIT_TEST(route)
BOOST_CHECK( ! tester.activeOut );
BOOST_CHECK_EQUAL( tester.throttles, 1 );
BOOST_CHECK( tester.passiveIn.throttled() );
BOOST_CHECK( ! activeSource.output );
BOOST_CHECK( ! activeSource );
BOOST_CHECK( ! tester.event.enabled() );
passiveSink.input.unthrottle();
BOOST_CHECK( activeSource.output );
BOOST_CHECK( activeSource );
BOOST_CHECK( tester.event.enabled() );
// Now throttle the passive source by exhausting the queue
BOOST_CHECK( p1 == activeSink.request() );
......@@ -146,18 +145,29 @@ BOOST_AUTO_UNIT_TEST(route)
BOOST_CHECK( ! tester.activeIn );
BOOST_CHECK_EQUAL( tester.throttles, 1 );
BOOST_CHECK( tester.passiveOut.throttled() );
BOOST_CHECK( ! activeSink.input );
BOOST_CHECK( ! activeSink );
BOOST_CHECK( ! tester.event.enabled() );
passiveSource.submit(p1);
BOOST_CHECK( activeSink.input );
BOOST_CHECK( activeSink );
BOOST_CHECK( tester.event.enabled() );
// Check correct combination of multiple throttling events
activeSink.request();
BOOST_CHECK( ! tester.event.enabled() );
passiveSink.input.throttle();
BOOST_CHECK( ! tester.event.enabled() );
passiveSource.submit(p1);
BOOST_CHECK( ! tester.event.enabled() );
passiveSink.input.unthrottle();
BOOST_CHECK( tester.event.enabled() );
tester.rt->autoThrottling(false);
BOOST_CHECK( p1 == activeSink.request() );
BOOST_CHECK( passiveSource.output.throttled() );
BOOST_CHECK( activeSink.input );
BOOST_CHECK( activeSink );
}
///////////////////////////////cc.e////////////////////////////////////////
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment