Completed first stage of PPI API specification
g0dil [Mon, 7 May 2007 14:14:39 +0000 (14:14 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@238 270642c3-0616-0410-b53a-bc976706d245

PPI/Connectors.hh
PPI/Events.hh [new file with mode: 0644]
PPI/Mainpage.dox
PPI/Module.hh
PPI/Queueing.hh [new file with mode: 0644]
PPI/Route.hh [new file with mode: 0644]

index 907d5a9..1b299e2 100644 (file)
@@ -49,6 +49,9 @@
 namespace senf {
 namespace ppi {
 
+    ///@{
+    ///\addtogroup connectors
+
     /** \brief Connector baseclass
 
         This connector provides access to the generic connector facilities. This includes the
@@ -83,8 +86,6 @@ namespace ppi {
             notifications
 
         The accumulative throttling state is generated by combining all sub-states.
-
-        \ingroup connectors
      */
     class PassiveConnector 
         : public virtual Connector
@@ -130,8 +131,6 @@ namespace ppi {
         Active connectors do not handle any throttling state, they just receive the
         notifications. These notifications should then either be processed by the module or be
         forwarded to other connectors.
-
-        \ingroup connectors
      */
     class ActiveConnector 
         : public virtual Connector
@@ -176,7 +175,18 @@ namespace ppi {
         packets in batches or generating multiple output packets from a single input packet. The
         queues have the potential to greatly simplify the module implementations.
 
-        \ingroup connectors
+        \implementation Which container to use?
+            \li list has good insertion and deletion properties on both ends but it costs a dynamic
+                memory allocation for every insertion. A very good property is, that iterators stay
+                valid across insertions/deletions
+            \li vector is fast and has good amortized dynamic allocation properties. However, it is
+                quite unusable as a queue
+            \li deque has comparable dynamic allocation properties as vector but also has good
+                insertion/removal properties on both ends.
+
+            So probably we will use a deque. I'd like a container which keeps iterators intact on
+            isertion/deletion but I believe that list is just to expensive since every packet will
+            be added to the queue before it can be processed.
      */
     class InputConnector 
         : public virtual Connector
@@ -232,8 +242,6 @@ namespace ppi {
         An output connector sends out packets. It may be either an ActiveConnector or a
         PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
         the queueing of the connected input.
-
-        \ingroup connectors
      */
     class OutputConnector 
         : public virtual Connector
@@ -251,7 +259,13 @@ namespace ppi {
 
     /** \brief Combination of PassiveConnector and InputConnector
 
-        \ingroup connectors
+        In addition to the native and the forwarded throttling state, the PassiveInput manages a
+        queue throttling state. This state is automatically managed by a queueing discipline. The
+        standard queueing discipline is ThresholdQueueing, which throttles the connection whenever
+        the queue length reaches the high threshold and unthrottles the connection when the queue
+        reaches the low threshold. The default queueing discpiline is
+        <tt>ThresholdQueueing(1,0)</tt> which will throttle the input whenever the queue is
+        non-empty.
      */
     class PassiveInput 
         : public PassiveConnector, public InputConnector
@@ -259,13 +273,15 @@ namespace ppi {
     public:
         ActiveOutput & peer();
 
-        template <class QDisc>
-        QDisc const & qdisc(QDisc const & disc);
+        template <class QueueingDiscipline>
+        void qdisc(QueueingDiscipline const & disc); ///< Change the queueing discipline
+                                        /**< The queueing discipline is a class which provides the
+                                             QueueingDiscipline interface.
+                                             
+                                             \param[in] disc New queueing discipline */
     };
 
     /** \brief Combination of PassiveConnector and OutputConnector
-
-        \ingroup connectors
      */
     class PassiveOutput
         : public PassiveConnector, public OutputConnector
@@ -275,21 +291,17 @@ namespace ppi {
     };
 
     /** \brief Combination of ActiveConnector and InputConnector
-
-        \ingroup connectors
      */
     class ActiveInput
         : public ActiveConnector, public InputConnector
     {
     public:
-        void request();                 ///< request more packets without dequeing any packet
-
         PassiveOutput & peer();
+
+        void request();                 ///< request more packets without dequeing any packet
     };
 
     /** \brief Combination of ActiveConnector and OutputConnector
-
-        \ingroup connectors
      */
     class ActiveOutput
         : public ActiveConnector, public OutputConnector
@@ -298,6 +310,8 @@ namespace ppi {
         ActiveInput & peer();
     };
 
+    ///@}
+
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////
diff --git a/PPI/Events.hh b/PPI/Events.hh
new file mode 100644 (file)
index 0000000..d077ac4
--- /dev/null
@@ -0,0 +1,81 @@
+// 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 public header */
+
+#ifndef HH_Events_
+#define HH_Events_ 1
+
+// Custom includes
+
+//#include "Events.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace ppi {
+
+    /** \brief Generic event interface baseclass
+
+        The EventDescriptor baseclass provides an interface to manuplate events in a generic
+        way. This allows to register events or to temporarily disable event processing.
+     */ 
+    class EventDescriptor
+    {
+    public:
+        bool enabled(); ///< Check, whether the event is currently enabled
+        void enabled(bool); ///< Enable or disable the event
+
+    protected:
+        typedef unspecified CallbackType; ///< Fixed type of the (internal) event handler.
+
+        void register(CallbackType handler); ///< Register the event
+        void unregister(); ///< Unregister the event
+
+    private:
+        virtual void v_register(CallbackType handler) = 0; ///< Called to register the event
+        virtual void v_unregister() = 0; ///< Called to unregister the event
+        virtual void v_enable() = 0;    ///< Called to enable the event delivery
+        virtual void v_disable() = 0;   ///< Called to disable the event delilvery
+        virtual void v_process() = 0;   ///< Called whenever the event is signaled
+                                        /**< This virtual method is called \e after every call to
+                                             the event handler to provide a hook for further
+                                             processing (example: calculate the next time, an
+                                             interval timer expires) */
+
+        bool enabled_;
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Events.cci"
+//#include "Events.ct"
+//#include "Events.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// End:
index 6438694..99e54f6 100644 (file)
     modules. <em>ASI/MPEG</em> and <em>Net</em> are external I/O ports which are integrated via the
     <em>TAP</em>, <em>ASI Out</em> and <em>Raw Sock</em> modules using external events.
 
+    \section design Design considerations
+
+    The PPI interface is designed to be as simple as possible. It provides sane defaults for all
+    configurable parameters to simplify getting started. It also automates all resource
+    management. Especially to simplify resource management, the PPI will take many configuration
+    objects by value. Even though this is not as efficient, it frees the user from most resource
+    management chores. This decision does not affect the runtime performance since it only applies
+    to the configuration part.
+
     \section packets Packets
 
     The PPI processes packets and uses the <a href="@TOPDIR@/Packets/doc/html/index.html">Packet
index aefe9a1..6d3d634 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Module public header */
+    \brief Module public header 
+*/
 
 #ifndef HH_Module_
 #define HH_Module_ 1
 
 // Custom includes
 #include <boost/utility.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 
 //#include "Module.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -39,7 +41,7 @@ namespace ppi {
         with interfaces to several PPI facilities:
         
         \li Connector management
-        \li Flow management
+        \li Flow management (routing)
         \li Event handling
 
         To provide internal bookkeeping, most access to the PPI infrastructure is managed through
@@ -56,7 +58,8 @@ namespace ppi {
         ~Module();
 
         template <class Source, class Target>
-        Route route(Source const & source, Target const & target); ///< Define flow information
+        Route<Source, Target> & route(Source const & source, Target const & target); 
+                                        ///< Define flow information
                                         /**< Using the route() and noroute() members, the
                                              information flow within the module is defined. Routing
                                              may be specified either between inputs, outputs and
@@ -74,7 +77,7 @@ namespace ppi {
 
                                              The return value may be used to alter routing
                                              parameters like throttling parameters.
-
+                                             
                                              \param[in] source Data source, object which controlls
                                                  incoming data
                                              \param[in] target Data target, object which controlls
@@ -82,22 +85,19 @@ namespace ppi {
                                              \returns Route instance describing this route */
 
         template <class Connector>
-        void noroute(Connector const & connector); ///<Define terminal connectors
-                                        /**<
-            
-                                            The noroute() member explicitly declares, that a
-                                            connector is terminal and does not directly
-                                            receive/forward data from/to some other
-                                            connector. <em>It is mandatory to define routing
-                                            information for terminal connectors</em>.
-
-                                            See the route() documentation for more on routing
+        void noroute(Connector const & connector); ///< Define terminal connectors
+                                        /**< The noroute() member explicitly declares, that a
+                                             connector is terminal and does not directly
+                                             receive/forward data from/to some other
+                                             connector. <em>It is mandatory to define routing
+                                             information for terminal connectors</em>.
 
-                                            \param[in] connector Terminal connector to declare */
+                                             See the route() documentation for more on routing
+                                             
+                                             \param[in] connector Terminal connector to declare */
 
         template <class Target, class Descriptor>
-        typename Descriptor::EventBinding const registerEvent(Target target, 
-                                                              Descriptor const & descriptor);
+        typename Descriptor & registerEvent(Target target, Descriptor const & descriptor);
                                         ///< Register an external event
                                         /**< The \a target argument may be either an arbitrary
                                              callable object or it may be a member function pointer
@@ -116,14 +116,46 @@ namespace ppi {
                                              delivery or to remove the binding explicitly. Depending
                                              on the type of event, other operations may be
                                              possible. See the event descriptor documentation.
-            
-                                            \param[in] target The handler to call whenever the event
-                                                is signaled
-                                            \param[in] descriptor The type of event to register
-                                            \returns An event binding instance of the appropriate
-                                                type. */
+
+                                             \param[in] target The handler to call whenever the event
+                                                 is signaled
+                                             \param[in] descriptor The type of event to register
+                                             \returns An event binding instance of the appropriate
+                                                 type. */
+
+        boost::posix_time::ptime eventTime(); ///< Return timestamp of the currently processing event
     };
 
+    /** \brief Automatically manage dynamic module deallocation
+
+        The dynamicModule helper will create a new dynamically managed module instance.
+
+        The \a args template parameter is only a placeholder. All arguments to dynamicModule will be
+        passed to the Module constructor.
+     */
+    template <class Module, class Args>
+    unspecified dynamicModule(Args args);
+
+
+    /** \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);
+
+    /** \brief Connect connectors via an adaptor module
+        
+        This connect() overload will insert an additional adaptor module into the connection. The
+        Adaptor module must have two connectors, \a input and \a output. The call will setup the
+        connections \a source to \a input and \a output to \a target. Each connector pair must be
+        compatible.
+     */
+    template <class Source, class Target, class Adaptor)
+    Adaptor const &  connect(Source const & source, Target const & target, 
+                             Adaptor const & adaptor);
+
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////
diff --git a/PPI/Queueing.hh b/PPI/Queueing.hh
new file mode 100644 (file)
index 0000000..daf59a8
--- /dev/null
@@ -0,0 +1,76 @@
+// 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 Queueing public header */
+
+#ifndef HH_Queueing_
+#define HH_Queueing_ 1
+
+// Custom includes
+
+//#include "Queueing.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace ppi {
+
+    /** \brief Queueing discipline base class
+
+        QueueingDescipline derived classes define the generation of throttling notifications. The
+        QueueingDiscipline is called whenever the packets are entered or removed from the queue. The
+        queueing discipline then determines the new throttling state of the queue.
+
+        \important The QueueingDiscipline will \e never drop packets explicitly. This is left to the
+        operating system by sending throttling events. The PPI will never loose a packet internally
+        (if not a module explicitly does so), however it may disable reception of new incoming
+        packets which will then probably dropped by the operating system.
+     */
+    class QueueingDiscipline
+    {
+    public:
+        enum Event { ENQUEUE, DEQUEUE }; ///< Possible queueing events
+        enum State { THROTTLED, UNTHROTTLED }; ///< Possible queueing states
+
+        State update(PassiveInput & input, Event event) = 0; ///< Calculate new queueing state
+                                        /**< Whenever the queue is manipulated, this member is
+                                             called to calculate the new throttling state.
+                                             
+                                             \param[in] input Connector holding the queue
+                                             \param[in] event Type of event triggering the upate
+                                             \returns new throttling state */
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Queueing.cci"
+//#include "Queueing.ct"
+//#include "Queueing.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// End:
diff --git a/PPI/Route.hh b/PPI/Route.hh
new file mode 100644 (file)
index 0000000..b09925d
--- /dev/null
@@ -0,0 +1,81 @@
+// 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 Route public header */
+
+#ifndef HH_Route_
+#define HH_Route_ 1
+
+// Custom includes
+
+//#include "Route.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace ppi {
+
+    template <class Source, class Target>
+    class Route
+    {
+    public:
+        void autoThrottling(bool state); ///< Change automatic throttle notification forwarding
+                                        /**< By default, throttle notifications are automatically
+                                             forwarded from active to passive connectors. This may
+                                             be disabled by setting the authoThrottling state to \c
+                                             false.
+                                             
+                                             This member only exists if
+                                             \li \a Source or \a Target is an event
+                                             \li one of \a Source and \a Target is an active
+                                                 connector and the other is a passive connector.
+
+                                             Routing from/to an event to/from a passive connector
+                                             will automatically create throttling notifications on
+                                             the connector whenever the event is disabled. Routing
+                                             form/to an event to/from an active connector will
+                                             disable the event whenever a throttling notification
+                                             comes in. Respective for unthrottle notifications.
+
+                                             \param[in] state New throttle forwarding state 
+
+                                             \implementation This class will be implemented using a
+                                                 baseclass, this template and several
+                                                 specializations. However, this is an implementation
+                                                 detail which does not affect the exposed
+                                                 interface. */
+    };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Route.cci"
+//#include "Route.ct"
+//#include "Route.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// End: