From: g0dil Date: Mon, 7 May 2007 14:14:39 +0000 (+0000) Subject: Completed first stage of PPI API specification X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=89efe5f504c400212090aba703c7ee385f483c64;p=senf.git Completed first stage of PPI API specification git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@238 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index 907d5a9..1b299e2 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -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 + ThresholdQueueing(1,0) 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 - QDisc const & qdisc(QDisc const & disc); + template + 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 index 0000000..d077ac4 --- /dev/null +++ b/PPI/Events.hh @@ -0,0 +1,81 @@ +// 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 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 + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// End: diff --git a/PPI/Mainpage.dox b/PPI/Mainpage.dox index 6438694..99e54f6 100644 --- a/PPI/Mainpage.dox +++ b/PPI/Mainpage.dox @@ -48,6 +48,15 @@ modules. ASI/MPEG and Net are external I/O ports which are integrated via the TAP, ASI Out and Raw Sock 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 Packet diff --git a/PPI/Module.hh b/PPI/Module.hh index aefe9a1..6d3d634 100644 --- a/PPI/Module.hh +++ b/PPI/Module.hh @@ -19,13 +19,15 @@ // 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 +#include //#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 - Route route(Source const & source, Target const & target); ///< Define flow information + Route & 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 - void noroute(Connector const & connector); ///It is mandatory to define routing - information for terminal connectors. - - 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. It is mandatory to define routing + information for terminal connectors. - \param[in] connector Terminal connector to declare */ + See the route() documentation for more on routing + + \param[in] connector Terminal connector to declare */ template - 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 + unspecified dynamicModule(Args args); + + + /** \brief Connect compatible connectors + + connect() will connect two compatible connectors: One connector must be active, the other + passive. + */ + template + 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 +// +// 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 + + +// 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 index 0000000..b09925d --- /dev/null +++ b/PPI/Route.hh @@ -0,0 +1,81 @@ +// 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 Route public header */ + +#ifndef HH_Route_ +#define HH_Route_ 1 + +// Custom includes + +//#include "Route.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace ppi { + + template + 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 + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// End: