From: g0dil Date: Thu, 16 Aug 2007 11:22:14 +0000 (+0000) Subject: PPI: Add support for multiple notify sources per notify target X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=550a30f99f2edbe72434c1b5f2a225320d0ef4ca;p=senf.git PPI: Add support for multiple notify sources per notify target PPI: Add boolean test for debug modules git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@392 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/PPI/Connectors.cc b/PPI/Connectors.cc index 7fe75a0..058a85c 100644 --- a/PPI/Connectors.cc +++ b/PPI/Connectors.cc @@ -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 diff --git a/PPI/Connectors.cci b/PPI/Connectors.cci index 3862aab..a046feb 100644 --- a/PPI/Connectors.cci +++ b/PPI/Connectors.cci @@ -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 diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index 24b3bed..6d47b63 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -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 Routes; + Routes routes_; + friend class senf::ppi::ForwardingRoute; }; @@ -194,6 +200,8 @@ namespace connector { notifications. */ void onUnthrottle(); + bool throttled() const; + PassiveConnector & peer() const; protected: diff --git a/PPI/DebugModules.cci b/PPI/DebugModules.cci index 58f367d..278aac3 100644 --- a/PPI/DebugModules.cci +++ b/PPI/DebugModules.cci @@ -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 diff --git a/PPI/DebugModules.hh b/PPI/DebugModules.hh index 8730ad7..1a38d4b 100644 --- a/PPI/DebugModules.hh +++ b/PPI/DebugModules.hh @@ -28,6 +28,7 @@ // Custom includes #include +#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 { 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 { public: connector::ActiveInput input; @@ -83,6 +88,8 @@ namespace debug { ActivePacketSink(); Packet request(); + + bool boolean_test() const; }; class PassivePacketSink diff --git a/PPI/Events.cc b/PPI/Events.cc new file mode 100644 index 0000000..e5dc53a --- /dev/null +++ b/PPI/Events.cc @@ -0,0 +1,63 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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: diff --git a/PPI/Events.cci b/PPI/Events.cci index f511f40..600fc37 100644 --- a/PPI/Events.cci +++ b/PPI/Events.cci @@ -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_ diff --git a/PPI/Events.hh b/PPI/Events.hh index fffd59e..698a433 100644 --- a/PPI/Events.hh +++ b/PPI/Events.hh @@ -25,6 +25,7 @@ #define HH_Events_ 1 // Custom includes +#include #include #include "predecl.hh" @@ -67,8 +68,13 @@ namespace ppi { void notifyThrottle(); void notifyUnthrottle(); + void registerRoute(ForwardingRoute & route); + bool enabled_; + typedef std::vector Routes; + Routes routes_; + friend class ForwardingRoute; }; diff --git a/PPI/Route.cci b/PPI/Route.cci index f0e2279..252a37c 100644 --- a/PPI/Route.cci +++ b/PPI/Route.cci @@ -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 diff --git a/PPI/Route.ct b/PPI/Route.ct index fb1cc0c..fc6ef5b 100644 --- a/PPI/Route.ct +++ b/PPI/Route.ct @@ -55,6 +55,15 @@ senf::ppi::detail::ForwardingRouteImplementation::v_notifyUnthrot } } +template +prefix_ bool senf::ppi::detail::ForwardingRouteImplementation::v_throttled() + const +{ + return this->autoThrottling() && ( + throttled(this->source(),boost::mpl::bool_::notifySource>()) || + throttled(this->target(),boost::mpl::bool_::notifySource>()) ); +} + ///////////////////////////////ct.e//////////////////////////////////////// #undef prefix_ diff --git a/PPI/Route.cti b/PPI/Route.cti index a136aff..214468e 100644 --- a/PPI/Route.cti +++ b/PPI/Route.cti @@ -46,6 +46,12 @@ prefix_ senf::ppi::Route::Route(module::Module & module, Source & // protected members template +prefix_ void senf::ppi::ForwardingRoute::registerRoute(T & ob) +{ + ob.registerRoute(*this); +} + +template prefix_ void senf::ppi::ForwardingRoute::notifyThrottle(T & ob) { ob.notifyThrottle(); @@ -62,12 +68,14 @@ prefix_ void senf::ppi::ForwardingRoute::notifyUnthrottle(T & ob) template prefix_ Source & senf::ppi::detail::BaseRouteImplementation::source() + const { return *source_; } template prefix_ Target & senf::ppi::detail::BaseRouteImplementation::target() + const { return *target_; } @@ -93,8 +101,8 @@ senf::ppi::detail::ForwardingRouteImplementation:: ForwardingRouteImplementation(module::Module & module, Source & source, Target & target) : Base(module,source,target) { - registerRoute(source, boost::mpl::bool_::notifySource>()); - registerRoute(target, boost::mpl::bool_::notifySource>()); + registerRoute(source); + registerRoute(target); } //////////////////////////////////////// @@ -103,44 +111,48 @@ ForwardingRouteImplementation(module::Module & module, Source & source, Target & template template prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -registerRoute(T & ob, boost::mpl::bool_ const &) +notifyThrottle(T & ob, boost::mpl::bool_ const &) { - ForwardingRoute::registerRoute(ob); + ForwardingRoute::notifyThrottle(ob); } template template prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -registerRoute(T & ob, boost::mpl::bool_ const &) +notifyThrottle(T & ob, boost::mpl::bool_ const &) {} template template prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -notifyThrottle(T & ob, boost::mpl::bool_ const &) +notifyUnthrottle(T & ob, boost::mpl::bool_ const &) { - ForwardingRoute::notifyThrottle(ob); + ForwardingRoute::notifyUnthrottle(ob); } template template prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -notifyThrottle(T & ob, boost::mpl::bool_ const &) +notifyUnthrottle(T & ob, boost::mpl::bool_ const &) {} template template -prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -notifyUnthrottle(T & ob, boost::mpl::bool_ const &) +prefix_ bool senf::ppi::detail::ForwardingRouteImplementation:: +throttled(T & ob, boost::mpl::bool_ const &) + const { - ForwardingRoute::notifyUnthrottle(ob); + return ob.throttled(); } template template -prefix_ void senf::ppi::detail::ForwardingRouteImplementation:: -notifyUnthrottle(T & ob, boost::mpl::bool_ const &) -{} +prefix_ bool senf::ppi::detail::ForwardingRouteImplementation:: +throttled(T & ob, boost::mpl::bool_ const &) + const +{ + return false; +} /////////////////////////////////////////////////////////////////////////// // senf::ppi::detail::RouteImplementation2 diff --git a/PPI/Route.hh b/PPI/Route.hh index f765152..88722c2 100644 --- a/PPI/Route.hh +++ b/PPI/Route.hh @@ -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 void registerRoute(T & ob); template void notifyThrottle(T & ob); template 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_; diff --git a/PPI/Route.ih b/PPI/Route.ih index 149b9e9..b99d93d 100644 --- a/PPI/Route.ih +++ b/PPI/Route.ih @@ -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 void registerRoute(T & ob, boost::mpl::bool_ const &); - template void registerRoute(T & ob, boost::mpl::bool_ const &); - // send a throttle/unthrottle notification only if the second argument is a 'true' type template void notifyThrottle(T & ob, boost::mpl::bool_ const &); template void notifyThrottle(T & ob, boost::mpl::bool_ const &); template void notifyUnthrottle(T & ob, boost::mpl::bool_ const &); template void notifyUnthrottle(T & ob, boost::mpl::bool_ const &); + template bool throttled(T & ob, boost::mpl::bool_ const &) const; + template bool throttled(T & ob, boost::mpl::bool_ 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 diff --git a/PPI/Route.test.cc b/PPI/Route.test.cc index 45b45ca..a70d869 100644 --- a/PPI/Route.test.cc +++ b/PPI/Route.test.cc @@ -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////////////////////////////////////////