PPI: Fix resource management on module destruction
g0dil [Fri, 17 Aug 2007 08:08:43 +0000 (08:08 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@394 270642c3-0616-0410-b53a-bc976706d245

14 files changed:
PPI/Connectors.cci
PPI/Connectors.test.cc
PPI/DebugModules.hh
PPI/EventManager.cc [new file with mode: 0644]
PPI/EventManager.hh
PPI/Module.cci
PPI/Module.hh
PPI/Module.test.cc
PPI/Route.test.cc
PPI/SocketReader.hh
PPI/SocketWriter.hh
PPI/SocketWriter.test.cc
PPI/detail/EventBinding.cci
PPI/detail/EventBinding.hh

index a046feb..1f3f192 100644 (file)
@@ -53,7 +53,10 @@ prefix_ senf::ppi::connector::Connector::Connector()
 {}
 
 prefix_ senf::ppi::connector::Connector::~Connector()
-{}
+{
+    if (peer_)
+        peer_->peer_ = 0;
+}
 
 prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
 {
index 80548f2..feb7266 100644 (file)
@@ -161,6 +161,8 @@ namespace {
     class PassiveInputTest
         : public ppi::module::Module
     {
+        SENF_PPI_MODULE(PassiveInputTest);
+
     public:
         ppi::connector::PassiveInput input;
 
index 1a38d4b..14fbb02 100644 (file)
@@ -44,6 +44,8 @@ namespace debug {
         : public Module, 
           public SafeBool<ActivePacketSource>
     {
+        SENF_PPI_MODULE(ActivePacketSource);
+
     public:
         connector::ActiveOutput output;
 
@@ -57,6 +59,8 @@ namespace debug {
     class PassivePacketSource
         : public Module
     {
+        SENF_PPI_MODULE(PassivePacketSource);
+
         typedef std::deque<Packet> Queue;
 
     public:
@@ -82,6 +86,8 @@ namespace debug {
         : public Module,
           public SafeBool<ActivePacketSink>
     {
+        SENF_PPI_MODULE(ActivePacketSink);
+
     public:
         connector::ActiveInput input;
 
@@ -95,6 +101,8 @@ namespace debug {
     class PassivePacketSink
         : public Module
     {
+        SENF_PPI_MODULE(PassivePacketSink);
+
         typedef std::deque<Packet> Queue;
 
     public:
diff --git a/PPI/EventManager.cc b/PPI/EventManager.cc
new file mode 100644 (file)
index 0000000..1b3e16b
--- /dev/null
@@ -0,0 +1,67 @@
+// $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 EventManager non-inline non-template implementation */
+
+#include "EventManager.hh"
+//#include "EventManager.ih"
+
+// Custom includes
+#include <boost/lambda/lambda.hpp>
+
+//#include "EventManager.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::EventManager
+
+////////////////////////////////////////
+// private members
+
+prefix_ void senf::ppi::EventManager::destroyModule(module::Module & module)
+{
+    using boost::lambda::_1;
+
+    // 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());
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "EventManager.mpp"
+
+\f
+// 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:
index 0c428ca..18f41d1 100644 (file)
@@ -84,6 +84,8 @@ namespace ppi {
     protected:
 
     private:
+        void destroyModule(module::Module & module);
+
         typedef boost::ptr_vector<detail::EventBindingBase> EventRegistrations;
         EventRegistrations registrations_;
 
@@ -92,6 +94,7 @@ namespace ppi {
         boost::posix_time::ptime eventTime_;
 
         friend class detail::EventBindingBase;
+        friend class module::Module;
     };
 
 }}
index 382ac57..533fbd3 100644 (file)
@@ -59,6 +59,11 @@ prefix_ void senf::ppi::module::Module::noroute(connector::Connector & connector
     connector.setModule(*this);
 }
 
+prefix_ void senf::ppi::module::Module::destroy()
+{
+    eventManager().destroyModule(*this);
+}
+
 ////////////////////////////////////////
 // private members
 
index 0002b05..c1b0a98 100644 (file)
@@ -124,6 +124,10 @@ namespace module {
         boost::posix_time::ptime eventTime(); ///< Return timestamp of the currently processing
                                               ///< event
 
+        void destroy();
+
+        virtual void macro_SENF_PPI_MODULE_missing() = 0;
+
     private:
         virtual void init();
 
@@ -144,13 +148,11 @@ namespace module {
         friend class senf::ppi::ModuleManager;
     };
 
-    /** \brief Connect compatible connectors
-
-        connect() will connect two compatible connectors: One connector must be active, the other
-        passive.
-     */
-    template <class Source, class Target>
-    void connect(Source const & source, Target const & target);
+#   define SENF_PPI_MODULE(name)                                                                  \
+    public:                                                                                       \
+        ~ name() { destroy(); }                                                                   \
+        void macro_SENF_PPI_MODULE_missing() {}                                                   \
+    private:
 
 }}}
 
index 1fe9b7b..c54ef51 100644 (file)
@@ -44,6 +44,8 @@ namespace debug = ppi::module::debug;
 namespace {
     class TestModule : public ppi::module::Module
     {
+        SENF_PPI_MODULE(TestModule);
+
     public:
         connector::ActiveOutput output;
 
index a70d869..f31b8a9 100644 (file)
@@ -47,6 +47,8 @@ namespace debug = module::debug;
 namespace {
     class RouteTester : public module::Module
     {
+        SENF_PPI_MODULE(RouteTester);
+
     public:
         connector::ActiveInput activeIn;
         connector::PassiveInput passiveIn;
index 7c348f2..5c0ca9e 100644 (file)
@@ -91,6 +91,8 @@ namespace module {
     class ActiveSocketReader 
         : public Module
     {
+        SENF_PPI_MODULE(ActiveSocketReader);
+
     public:
         typedef typename Reader::Handle Handle; ///< Handle type requested by the reader
 
index 233322c..263f349 100644 (file)
@@ -87,6 +87,8 @@ namespace module {
     template <class Writer=PacketWriter>
     class ActiveSocketWriter : public Module
     {
+        SENF_PPI_MODULE(ActiveSocketWriter);
+
     public:
         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
 
@@ -125,6 +127,8 @@ namespace module {
     template <class Writer=PacketWriter>
     class PassiveSocketWriter : public Module
     {
+        SENF_PPI_MODULE(PassiveSocketWriter);
+
     public:
         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
 
index 5e40772..78814ca 100644 (file)
@@ -64,7 +64,6 @@ BOOST_AUTO_UNIT_TEST(passiveSocketWriter)
 
     senf::UDPv4ClientSocketHandle inputSocket;
     inputSocket.bind(senf::INet4SocketAddress("localhost:44344"));
-    inputSocket.blocking(false);
     senf::ppi::init();
     source.submit(p);
 
@@ -85,8 +84,7 @@ BOOST_AUTO_UNIT_TEST(activeSocketWriter)
 
     senf::UDPv4ClientSocketHandle inputSocket;
     inputSocket.bind(senf::INet4SocketAddress("localhost:44344"));
-    inputSocket.blocking(false);
-    senf::Scheduler::instance().timeout(1000, &timeout);
+    senf::Scheduler::instance().timeout(100, &timeout);
     source.submit(p);
     senf::ppi::run();
 
index ad4e89e..7e27b3a 100644 (file)
@@ -24,6 +24,7 @@
     \brief EventBinding inline non-template implementation */
 
 // Custom includes
+#include "../Events.hh"
 
 #define prefix_ inline
 ///////////////////////////////cci.p///////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 // senf::ppi::detail::EventBindingBase
 
+prefix_ senf::ppi::detail::EventBindingBase::~EventBindingBase()
+{
+    descriptor_->enabled(false);
+}
+
 ////////////////////////////////////////
 // protected members
 
@@ -51,5 +57,5 @@ prefix_ senf::ppi::detail::EventBindingBase::EventBindingBase(EventManager & man
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
+// compile-command: "scons -u ../test"
 // End:
index addda33..468e713 100644 (file)
@@ -40,6 +40,9 @@ namespace detail {
 
     class EventBindingBase
     {
+    public:
+        ~EventBindingBase();
+        
     protected:
         EventBindingBase(EventManager & manager, module::Module & module, 
                          EventDescriptor & descriptor);
@@ -50,6 +53,8 @@ namespace detail {
         EventManager * manager_;
         module::Module * module_;
         EventDescriptor * descriptor_;
+
+        friend class senf::ppi::EventManager;
     };
 
     template <class EventType, class Self>