X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=PPI%2FModule.hh;h=7e6e21ea7d90a94d8b4f809889f953375d7ac22d;hb=21bad90912447cd2d390112cf2d2a7d383ad8058;hp=aefe9a1aee51948c2a130e5abbdd0c414cfffda7;hpb=a4887e674af3fce4180cf7e14bedace928962025;p=senf.git diff --git a/PPI/Module.hh b/PPI/Module.hh index aefe9a1..7e6e21e 100644 --- a/PPI/Module.hh +++ b/PPI/Module.hh @@ -19,44 +19,168 @@ // 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 +#include "Scheduler/ClockService.hh" +#include "predecl.hh" //#include "Module.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { namespace ppi { +namespace module { - /** \brief Module baseclass + /** \namespace senf::ppi::module + \brief PPI Modules + + The modules build the PPI core. The PPI provides a set of general purpose infrastructure + modules. For concrete applications, additional application specific processing modules need + to be implemented. - senf::ppi::Module is the baseclass of all PPI modules. It provides the module implementation + \section module_impl Implementing Modules + + All modules derive from senf::ppi::module::Module. See this class for a documentation on how + to write new modules. + + \section infrastructure_modules General Purpose Modules + + The PPI provided general purpose modules can be grouped into several categories + + \li \ref io_modules receive external data or forward packets out of the PPI + \li \ref sourcesink_modules generate or absorb packets internally + \li \ref routing_modules forward packets within the network + \li \ref adapter_modules are used to connect incompatible connectors to each other + + \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter + */ + + /** \defgroup io_modules Input/Output Modules + + Input/Output Modules receive data from external sources or forward data from the PPI to + outside targets. + */ + + /** \defgroup sourcesink_modules Source/Sink Modules + + Source and Sink modules generate or absorb packets internally. In contrast to \ref + io_modules, they do not communicate outside the PPI. + */ + + /** \defgroup routing_modules Routing Modules + + Routing modules perform packet forwarding within the network. They do not process the packet + data, they just route it. + */ + + /** \defgroup adapter_modules Adapter Modules + + Adapter modules adapt incompatible connectors to each other. They allow connection a pair of + active or passive connectors. + */ + + /** \brief Module base-class + + senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation 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 - this base class. + this base class. This is an example module specification: + \code + class SomeModule : public senf::ppi::module::Module + { + SENF_PPI_MODULE(SomeModule); + + senf::FileHandle handle; + + // If needed, define events + senf::ppi::IOEvent event; + + public: + // Define connectors. Any number and type of connectors may be defined. Connectors + // must be public since they need to be accessed to connect modules with each other. + senf::ppi::connector::PassiveInput input; + senf::ppi::connector::ActiveOutput output; + + SomeModule(senf::FileHandle h) + : handle ( h ), + event ( handle, senf::ppi::IOEvent::Read ) + { + // Set up routing. If some connector is not routed you need to explicitly state this + // using noroute() + route( input, output ); + route( event, output ) + .autoThrottling( false ); + + // Register event handlers + registerEvent( &SomeModule::read, event ); + + // Register passive connector handlers + input.onRequest( &SomeModule::outputRequest ); + + // If needed, you may register throttling event handlers + output.onThrottle( &SomeModule::throttle ); + output.onUnthrottle( &SomeModule::unthrottle ); + } - Instances of this class may be allocated either statically or dynamically. Dynamic instances - are automatically managed using the dynamicModule adaptor. + void read() { + // Called whenever the 'handle' is readable. Read data, do processing and so + // on. This example reads the data, puts it into an ethernet packet and sends the + // packet out via the active output. + output(senf::EthernetPacket::create(handle.read())) + } + + void outputRequest() { + // Called whenever a packet is sent into the input to. Here we just forward it to + // the output if it is an EthernetPacket + senf::EthernetPacket p (input().find(senf::nothrow)); + if (p) + output(p); + } + + void onThrottle() { + // Called whenever a throttle notification comes in. Here, we just disable the + // event (which is stupid since we should just not have disabled autoThrottling on + // the route but this is only an example which tries to be simple ...) + event.disable(); + } + + void onUnthrottle() { + // and for unthrottle notifications + event.enable(); + } + + }; + \endcode + + If your module only has a single input connector, you should call this connector \c + input. If it has only a single output connector, you should call it \c output. This allows + to setup connections without stating the connector explicitly (see senf::ppi::connect()). */ class Module : boost::noncopyable { + public: + virtual ~Module(); + protected: Module(); - ~Module(); template - Route route(Source const & source, Target const & target); ///< Define flow information + Route & route(Source & source, Target & 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,61 +198,99 @@ namespace ppi { The return value may be used to alter routing parameters like throttling parameters. - - \param[in] source Data source, object which controlls + + \param[in] source Data source, object which controls incoming data - \param[in] target Data target, object which controlls + \param[in] target Data target, object which controls outgoing data \returns Route instance describing this route */ - template - void noroute(Connector const & connector); ///It is mandatory to define routing - information for terminal connectors. + void noroute(connector::Connector & 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. - See the route() documentation for more on routing - - \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); + void registerEvent(Target target, Descriptor & descriptor); ///< Register an external event /**< The \a target argument may be either an arbitrary callable object or it may be a member function pointer pointing to a member function of the Module derived classed. The handler may \e optionally take an Argument - of type typename Descriptor::Event const - &. This object allows to access detailed - information on the event delivered. + of type Descriptor::Event const &. This object + allows to access detailed information on the event + delivered. The \a descriptor describes the event to signal. This + may be a timer event or some type of I/O event on a file descriptor or socket. - The return value may be used to modify the - binding. This allows to temporarily inhibit event - 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 */ + + ClockService::clock_type time() const; ///< Time-stamp of the currently processing event + /**< If available, this returns the scheduled time of the + event. */ + + ClockService::clock_type now() const; ///< Current time of the currently processing event + +#ifndef DOXYGEN + virtual void macro_SENF_PPI_MODULE_missing() = 0; +#endif + +#ifndef DOXYGEN + private: +#endif + virtual void init(); ///< Called just before the network is run + +#ifndef DOXYGEN + public: +#endif + void destroy(); + + private: + EventManager & eventManager() const; + ModuleManager & moduleManager() const; + + void registerConnector(connector::Connector & connector); + RouteBase & addRoute(std::auto_ptr route); + + typedef std::vector ConnectorRegistry; + ConnectorRegistry connectorRegistry_; + + typedef boost::ptr_vector RouteInfoBase; + RouteInfoBase routes_; + + template + friend class detail::RouteHelper; + friend class senf::ppi::ModuleManager; }; -}} + /** \brief Define PPI Module + + Every module must begin by using this macro. + + \see senf::ppi::module::Module + */ +# define SENF_PPI_MODULE(name) \ + public: \ + ~ name() { destroy(); } \ + void macro_SENF_PPI_MODULE_missing() {} \ + private: + +}}} ///////////////////////////////hh.e//////////////////////////////////////// -//#include "Module.cci" -//#include "Module.ct" +#include "Module.cci" +#include "Module.ct" //#include "Module.cti" #endif @@ -139,4 +301,6 @@ namespace ppi { // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: