From: g0dil Date: Tue, 27 Oct 2009 10:51:49 +0000 (+0000) Subject: PPI: Implement Connector and Event un-registration X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=69b25a4904fa86324aedc7147502255ce4117885;hp=66101f618adf223cf360dd891f82f6eae37930cb;p=senf.git PPI: Implement Connector and Event un-registration git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1510 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/PPI/AnnotationRouter.ct b/senf/PPI/AnnotationRouter.ct index 29a9cab..0e1bbef 100644 --- a/senf/PPI/AnnotationRouter.ct +++ b/senf/PPI/AnnotationRouter.ct @@ -26,6 +26,7 @@ //#include "AnnotationRouter.ih" // Custom includes +#include "Connectors.hh" #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// diff --git a/senf/PPI/Connectors.cc b/senf/PPI/Connectors.cc index debe7ec..065d36f 100644 --- a/senf/PPI/Connectors.cc +++ b/senf/PPI/Connectors.cc @@ -268,6 +268,13 @@ prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRout notifyRoutes_.push_back(&route); } +prefix_ void senf::ppi::connector::ActiveConnector::unregisterRoute(ForwardingRoute & route) +{ + NotifyRoutes::iterator i (std::find(notifyRoutes_.begin(), notifyRoutes_.end(), &route)); + if (i != notifyRoutes_.end()) + notifyRoutes_.erase(i); +} + /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::InputConnector diff --git a/senf/PPI/Connectors.cci b/senf/PPI/Connectors.cci index 2abd3b1..3f9ceee 100644 --- a/senf/PPI/Connectors.cci +++ b/senf/PPI/Connectors.cci @@ -26,6 +26,7 @@ // Custom includes #include #include +#include "Module.hh" #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// @@ -84,6 +85,12 @@ prefix_ bool senf::ppi::connector::Connector::connected() return peer_; } +prefix_ void senf::ppi::connector::Connector::unregisterConnector() +{ + if (module_) + module_->unregisterConnector(*this); +} + //////////////////////////////////////// // private members @@ -141,6 +148,13 @@ prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRou routes_.push_back(&route); } +prefix_ void senf::ppi::connector::PassiveConnector::unregisterRoute(ForwardingRoute & route) +{ + Routes::iterator i (std::find(routes_.begin(), routes_.end(), &route)); + if (i != routes_.end()) + routes_.erase(i); +} + // public members prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled() diff --git a/senf/PPI/Connectors.cti b/senf/PPI/Connectors.cti index b8f5bf3..598e7f1 100644 --- a/senf/PPI/Connectors.cti +++ b/senf/PPI/Connectors.cti @@ -66,6 +66,12 @@ prefix_ void senf::ppi::connector::detail::TypedOutputMixin::wr /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::PassiveConnector +prefix_ senf::ppi::connector::PassiveConnector::~PassiveConnector() +{ + // Must be here and NOT in base so it is called before destructing the routes_ member + unregisterConnector(); +} + template prefix_ void senf::ppi::connector::PassiveConnector::onRequest(Handler handler) { @@ -75,6 +81,12 @@ prefix_ void senf::ppi::connector::PassiveConnector::onRequest(Handler handler) /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::ActiveConnector +prefix_ senf::ppi::connector::ActiveConnector::~ActiveConnector() +{ + // Must be here and NOT in base so it is called before destructing the routes_ member + unregisterConnector(); +} + template prefix_ void senf::ppi::connector::ActiveConnector::onThrottle(Handler handler) { diff --git a/senf/PPI/Connectors.hh b/senf/PPI/Connectors.hh index c0b0b49..0dfe9cf 100644 --- a/senf/PPI/Connectors.hh +++ b/senf/PPI/Connectors.hh @@ -184,6 +184,8 @@ namespace connector { void trace(Packet const & p, char const * label); void throttleTrace(char const * label, char const * type); + + void unregisterConnector(); private: virtual std::type_info const & packetTypeID(); @@ -220,6 +222,8 @@ namespace connector { : public virtual Connector { public: + ~PassiveConnector(); + template void onRequest(Handler handler);///< Register I/O event handler /**< The registered handler will be called, whenever packets @@ -263,6 +267,7 @@ namespace connector { // called by ForwardingRoute to register a new route void registerRoute(ForwardingRoute & route); + void unregisterRoute(ForwardingRoute & route); typedef ppi::detail::Callback<>::type Callback; Callback callback_; @@ -291,6 +296,8 @@ namespace connector { { typedef ppi::detail::Callback<>::type Callback; public: + ~ActiveConnector(); + template void onThrottle(Handler handler); ///< Register throttle notification handler /**< The handler register here will be called, whenever a @@ -333,6 +340,7 @@ namespace connector { // called by ForwardingRoute to register a new route void registerRoute(ForwardingRoute & route); + void unregisterRoute(ForwardingRoute & route); Callback throttleCallback_; Callback unthrottleCallback_; diff --git a/senf/PPI/EventManager.cc b/senf/PPI/EventManager.cc index be2dc76..0b6a482 100644 --- a/senf/PPI/EventManager.cc +++ b/senf/PPI/EventManager.cc @@ -28,6 +28,7 @@ // Custom includes #include +#include //#include "EventManager.mpp" #define prefix_ @@ -42,13 +43,20 @@ prefix_ void senf::ppi::EventManager::destroyModule(module::Module & module) { using boost::lambda::_1; + namespace l = boost::lambda; - // boost::ptr_vector::erase(f,l) asserts !empty() .. why ?? - if (!registrations_.empty()) - registrations_.erase( - std::remove_if(registrations_.begin(), registrations_.end(), - ((&_1) ->* & detail::EventBindingBase::module_) == & module), - registrations_.end()); + registrations_.erase_if(l::bind(&detail::EventBindingBase::module_,_1) == &module); +} + +prefix_ void senf::ppi::EventManager::destroyEvent(EventDescriptor & event) +{ + using boost::lambda::_1; + namespace l = boost::lambda; + + SENF_ASSERT( + std::find_if(registrations_.begin(), registrations_.end(), + l::bind(&detail::EventBindingBase::descriptor_,_1) == &event) + == registrations_.end()); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/senf/PPI/EventManager.hh b/senf/PPI/EventManager.hh index 0f5fd9c..16f671b 100644 --- a/senf/PPI/EventManager.hh +++ b/senf/PPI/EventManager.hh @@ -87,6 +87,7 @@ namespace ppi { Descriptor & descriptor); void destroyModule(module::Module & module); + void destroyEvent(EventDescriptor & event); typedef boost::ptr_vector EventRegistrations; EventRegistrations registrations_; @@ -97,6 +98,7 @@ namespace ppi { friend class detail::EventBindingBase; friend class module::Module; + friend class EventDescriptor; }; }} diff --git a/senf/PPI/Events.cc b/senf/PPI/Events.cc index 7aa0298..f74a329 100644 --- a/senf/PPI/Events.cc +++ b/senf/PPI/Events.cc @@ -28,6 +28,7 @@ // Custom includes #include "Route.hh" +#include "EventManager.hh" //#include "Events.mpp" #define prefix_ @@ -36,6 +37,12 @@ /////////////////////////////////////////////////////////////////////////// // senf::ppi::EventDescriptor +prefix_ senf::ppi::EventDescriptor::~EventDescriptor() +{ + if (binding_) + binding_->manager().destroyEvent(*this); +} + prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle() { Routes::const_iterator i (routes_.begin()); diff --git a/senf/PPI/Events.cci b/senf/PPI/Events.cci index 8ba444a..3282ba5 100644 --- a/senf/PPI/Events.cci +++ b/senf/PPI/Events.cci @@ -25,6 +25,7 @@ // Custom includes #include +#include #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// @@ -32,9 +33,6 @@ /////////////////////////////////////////////////////////////////////////// // senf::ppi::EventDescriptor -prefix_ senf::ppi::EventDescriptor::~EventDescriptor() -{} - prefix_ bool senf::ppi::EventDescriptor::enabled() { return enabled_; @@ -61,6 +59,13 @@ prefix_ void senf::ppi::EventDescriptor::registerRoute(ForwardingRoute & route) routes_.push_back(&route); } +prefix_ void senf::ppi::EventDescriptor::unregisterRoute(ForwardingRoute & route) +{ + Routes::iterator i (std::find(routes_.begin(), routes_.end(), &route)); + if (i != routes_.end()) + routes_.erase(i); +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/PPI/Events.hh b/senf/PPI/Events.hh index 8e922cd..1025db5 100644 --- a/senf/PPI/Events.hh +++ b/senf/PPI/Events.hh @@ -36,6 +36,8 @@ namespace senf { namespace ppi { + + namespace detail { class EventBindingBase; } /** \defgroup event_group Events @@ -85,6 +87,7 @@ namespace ppi { void notifyUnthrottle(); void registerRoute(ForwardingRoute & route); + void unregisterRoute(ForwardingRoute & route); bool enabled_; bool throttled_; @@ -92,7 +95,10 @@ namespace ppi { typedef std::vector Routes; Routes routes_; + detail::EventBindingBase * binding_; + friend class ForwardingRoute; + friend class detail::EventBindingBase; }; /** \brief Internal: Callback forwarders diff --git a/senf/PPI/Module.cci b/senf/PPI/Module.cci index 3f0817d..73865c2 100644 --- a/senf/PPI/Module.cci +++ b/senf/PPI/Module.cci @@ -28,6 +28,9 @@ #include "Connectors.hh" #include "EventManager.hh" #include "ModuleManager.hh" +#include +#include +#include #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// @@ -62,6 +65,21 @@ prefix_ void senf::ppi::module::Module::registerConnector(connector::Connector & } } +prefix_ void senf::ppi::module::Module::unregisterConnector(connector::Connector & connector) +{ + ConnectorRegistry::iterator i (std::find(connectorRegistry_.begin(), connectorRegistry_.end(), + &connector)); + if (i != connectorRegistry_.end()) + connectorRegistry_.erase(i); + + routes_.erase_if(boost::bind(&RouteBase::hasConnector, _1, boost::cref(connector))); +} + +prefix_ void senf::ppi::module::Module::unregisterEvent(EventDescriptor & event) +{ + routes_.erase_if(boost::bind(&RouteBase::hasEvent, _1, boost::cref(event))); +} + prefix_ senf::ppi::RouteBase & senf::ppi::module::Module::addRoute(std::auto_ptr route) { @@ -74,6 +92,9 @@ senf::ppi::module::Module::addRoute(std::auto_ptr route) prefix_ senf::ppi::module::Module::~Module() { + SENF_ASSERT(connectorRegistry_.empty()); + SENF_ASSERT(routes_.empty()); + moduleManager().unregisterModule(*this); } diff --git a/senf/PPI/Module.hh b/senf/PPI/Module.hh index e4f2599..73f5385 100644 --- a/senf/PPI/Module.hh +++ b/senf/PPI/Module.hh @@ -40,6 +40,9 @@ namespace senf { namespace ppi { + + namespace detail { class EventBindingBase; } + namespace module { /** \namespace senf::ppi::module @@ -313,6 +316,9 @@ namespace module { ModuleManager & moduleManager() const; void registerConnector(connector::Connector & connector); + void unregisterConnector(connector::Connector & connector); + void unregisterEvent(EventDescriptor & event); + RouteBase & addRoute(std::auto_ptr route); typedef std::vector ConnectorRegistry; @@ -324,6 +330,8 @@ namespace module { template friend class detail::RouteHelper; friend class senf::ppi::ModuleManager; + friend class connector::Connector; + friend class senf::ppi::detail::EventBindingBase; }; /** \brief Define PPI Module diff --git a/senf/PPI/Route.cci b/senf/PPI/Route.cci index 0a3117a..4c45f95 100644 --- a/senf/PPI/Route.cci +++ b/senf/PPI/Route.cci @@ -36,6 +36,18 @@ prefix_ senf::ppi::RouteBase::~RouteBase() {} +prefix_ bool senf::ppi::RouteBase::hasConnector(connector::Connector const & conn) + const +{ + return v_hasConnector(conn); +} + +prefix_ bool senf::ppi::RouteBase::hasEvent(EventDescriptor const & event) + const +{ + return v_hasEvent(event); +} + //////////////////////////////////////// // protected members diff --git a/senf/PPI/Route.cti b/senf/PPI/Route.cti index c72ad31..d6ed64e 100644 --- a/senf/PPI/Route.cti +++ b/senf/PPI/Route.cti @@ -52,6 +52,12 @@ prefix_ void senf::ppi::ForwardingRoute::registerRoute(T & ob) } template +prefix_ void senf::ppi::ForwardingRoute::unregisterRoute(T & ob) +{ + ob.unregisterRoute(*this); +} + +template prefix_ void senf::ppi::ForwardingRoute::notifyThrottle(T & ob) { ob.notifyThrottle(); @@ -89,6 +95,57 @@ BaseRouteImplementation(module::Module & module, Source & source, Target & targe : Base(module), source_(&source), target_(&target) {} +//////////////////////////////////////// +// private members + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +v_hasConnector(connector::Connector const & conn) + const +{ + return isSame(conn, source()) || isSame(conn, target()); +} + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +v_hasEvent(EventDescriptor const & event) + const +{ + return isSame(event, source()) || isSame(event, target()); +} + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +isSame(connector::Connector const & conn, connector::Connector const & other) + const +{ + return &conn == &other; +} + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +isSame(connector::Connector const & conn, EventDescriptor const & other) + const +{ + return false; +} + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +isSame(EventDescriptor const & event, connector::Connector const & other) + const +{ + return false; +} + +template +prefix_ bool senf::ppi::detail::BaseRouteImplementation:: +isSame(EventDescriptor const & event, EventDescriptor const & other) + const +{ + return &event == &other; +} + /////////////////////////////////////////////////////////////////////////// // senf::ppi::detail::ForwardingRouteImplementation @@ -105,6 +162,15 @@ ForwardingRouteImplementation(module::Module & module, Source & source, Target & registerRoute(target); } +template +prefix_ +senf::ppi::detail::ForwardingRouteImplementation:: +~ForwardingRouteImplementation() +{ + unregisterRoute(this->source()); + unregisterRoute(this->target()); +} + //////////////////////////////////////// // private members diff --git a/senf/PPI/Route.hh b/senf/PPI/Route.hh index fb29305..7977031 100644 --- a/senf/PPI/Route.hh +++ b/senf/PPI/Route.hh @@ -57,10 +57,18 @@ namespace ppi { class is internal and not documented. */ #endif + bool hasConnector(connector::Connector const & conn) const; + ///< \c true, if route has connector \a conn + bool hasEvent(EventDescriptor const & event) const; + ///< \c true, if route has event \a event + protected: RouteBase(module::Module & module); private: + virtual bool v_hasConnector(connector::Connector const & conn) const = 0; + virtual bool v_hasEvent(EventDescriptor const & event) const = 0; + module::Module * module_; }; @@ -100,6 +108,7 @@ namespace ppi { // Called to register this route with the connectors forwarding information base template void registerRoute(T & ob); + template void unregisterRoute(T & ob); template void notifyThrottle(T & ob); template void notifyUnthrottle(T & ob); diff --git a/senf/PPI/Route.ih b/senf/PPI/Route.ih index 31a4e5b..901cf92 100644 --- a/senf/PPI/Route.ih +++ b/senf/PPI/Route.ih @@ -110,6 +110,14 @@ namespace detail { BaseRouteImplementation(module::Module & module, Source & source, Target & target); private: + bool v_hasConnector(connector::Connector const & conn) const; + bool v_hasEvent(EventDescriptor const & event) const; + + bool isSame(connector::Connector const & conn, connector::Connector const & other) const; + bool isSame(connector::Connector const & conn, EventDescriptor const & other) const; + bool isSame(EventDescriptor const & event, connector::Connector const & other) const; + bool isSame(EventDescriptor const & event, EventDescriptor const & other) const; + Source * source_; Target * target_; }; @@ -135,6 +143,7 @@ namespace detail { protected: ForwardingRouteImplementation(module::Module & module, Source & source, Target & target); + ~ForwardingRouteImplementation(); private: // send a throttle/unthrottle notification only if the second argument is a 'true' type diff --git a/senf/PPI/detail/EventBinding.cc b/senf/PPI/detail/EventBinding.cc index 65aa700..e1d5a4f 100644 --- a/senf/PPI/detail/EventBinding.cc +++ b/senf/PPI/detail/EventBinding.cc @@ -28,11 +28,19 @@ // Custom includes #include +#include //#include "EventBinding.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ senf::ppi::detail::EventBindingBase::~EventBindingBase() +{ + descriptor_->enabled(false); + module().unregisterEvent(*descriptor_); + descriptor_->binding_ = 0; +} + prefix_ void senf::ppi::detail::EventBindingBase::eventTime(ClockService::clock_type time) { // It's hard to make this inline because of a circular header dependency ... diff --git a/senf/PPI/detail/EventBinding.cci b/senf/PPI/detail/EventBinding.cci index 032d4bd..6a4cffc 100644 --- a/senf/PPI/detail/EventBinding.cci +++ b/senf/PPI/detail/EventBinding.cci @@ -32,11 +32,6 @@ /////////////////////////////////////////////////////////////////////////// // senf::ppi::detail::EventBindingBase -prefix_ senf::ppi::detail::EventBindingBase::~EventBindingBase() -{ - descriptor_->enabled(false); -} - prefix_ senf::ppi::EventManager & senf::ppi::detail::EventBindingBase::manager() const { @@ -56,7 +51,9 @@ prefix_ senf::ppi::detail::EventBindingBase::EventBindingBase(EventManager & man module::Module & module, EventDescriptor & descriptor) : manager_(&manager), module_(&module), descriptor_(&descriptor) -{} +{ + descriptor_->binding_ = this; +} ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/PPI/detail/EventBinding.hh b/senf/PPI/detail/EventBinding.hh index 97087c2..15a4318 100644 --- a/senf/PPI/detail/EventBinding.hh +++ b/senf/PPI/detail/EventBinding.hh @@ -59,6 +59,7 @@ namespace detail { EventDescriptor * descriptor_; friend class senf::ppi::EventManager; + friend class senf::ppi::EventDescriptor; }; /** \brief Internal: Callback forwarders