4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Module public header
27 #ifndef HH_SENF_PPI_Module_
28 #define HH_SENF_PPI_Module_ 1
32 #include <boost/utility.hpp>
33 #include <boost/ptr_container/ptr_vector.hpp>
34 #include <senf/Scheduler/ClockService.hh>
36 #include "ModuleManager.hh"
38 //#include "Module.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
44 namespace detail { class EventBindingBase; }
48 /** \namespace senf::ppi::module
51 The modules build the PPI core. The PPI provides a set of general purpose infrastructure
52 modules. For concrete applications, additional application specific processing modules need
55 \section module_impl Implementing Modules
57 All modules derive from senf::ppi::module::Module. See this class for a documentation on how
60 \section infrastructure_modules General Purpose Modules
62 The PPI provided general purpose modules can be grouped into several categories
64 \li \ref io_modules receive external data or forward packets out of the PPI
65 \li \ref routing_modules forward packets within the network
66 \li \ref adapter_modules are used to connect incompatible connectors to each other
69 /** \defgroup io_modules Source/Sink Modules
71 Source and Sink modules generate or absorb packets in some way: Reading data from a file
72 descriptor, discarding packets etc.
75 /** \defgroup routing_modules Routing Modules
77 Routing modules perform packet forwarding within the network. They do not process the packet
78 data, they just route it.
81 /** \defgroup adapter_modules Adapter Modules
83 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
84 active or passive connectors.
87 /** \brief Module base-class
89 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
90 with interfaces to several PPI facilities:
92 \li Connector management
93 \li Flow management (routing)
96 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
97 this base class. This is an example module specification:
99 class SomeModule : public senf::ppi::module::Module
101 SENF_PPI_MODULE(SomeModule);
103 senf::FileHandle handle;
105 // If needed, define events
106 senf::ppi::IOEvent event;
109 // Define connectors. Any number and type of connectors may be defined. Connectors
110 // must be public since they need to be accessed to connect modules with each other.
111 senf::ppi::connector::PassiveInput<> input;
112 senf::ppi::connector::ActiveOutput<> output;
114 SomeModule(senf::FileHandle h)
116 event ( handle, senf::ppi::IOEvent::Read )
118 // Set up routing. If some connector is not routed you need to explicitly state this
120 route( input, output );
121 route( event, output )
122 .autoThrottling( false );
124 // Register event handlers
125 registerEvent( event, &SomeModule::read );
127 // Register passive connector handlers
128 input.onRequest( &SomeModule::outputRequest );
130 // If needed, you may register throttling event handlers
131 output.onThrottle( &SomeModule::throttle );
132 output.onUnthrottle( &SomeModule::unthrottle );
136 // Called whenever the 'handle' is readable. Read data, do processing and so
137 // on. This example reads the data, puts it into an ethernet packet and sends the
138 // packet out via the active output.
139 output(senf::EthernetPacket::create(handle.read()))
142 void outputRequest() {
143 // Called whenever a packet is sent into the input to. Here we just forward it to
144 // the output if it is an EthernetPacket
145 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
151 // Called whenever a throttle notification comes in. Here, we just disable the
152 // event (which is stupid since we should just not have disabled autoThrottling on
153 // the route but this is only an example which tries to be simple ...)
157 void onUnthrottle() {
158 // and for unthrottle notifications
163 // Optional. Called after before running the module but after connections have been
164 // set up. This is either directly before senf::ppi::run() or senf::ppi::init() is
165 // called or, for modules created while the PPI is already running, after returning
166 // from all event handlers but before going back to the event loop.
172 If your module only has a single input connector, you should call this connector \c
173 input. If it has only a single output connector, you should call it \c output. This allows
174 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
176 \see \ref ppi_modules
179 : ModuleManager::Initializable, boost::noncopyable
188 template <class Source, class Target>
189 Route<Source, Target> & route(Source & source, Target & target);
191 Route<connector::InputConnector, connector::OutputConnector> &
192 route(connector::InputConnector & input, connector::OutputConnector & output);
193 ///< Define flow information
194 /**< Using the route() and noroute() members, the
195 information flow within the module is defined. Routing
196 may be defined between inputs, outputs and events. The
197 routing information is used to perform automatic
198 throttling. The throttling behavior may however be
201 Even if no automatic throttling is desired <em>it is
202 essential to define the flow information for all inputs
203 and outputs</em>. Without flow information important
204 internal state of the module cannot be
205 initialized. This includes, explicitly defining
206 terminal inputs and outputs using noroute. Event
207 routing is optional however.
209 The return value may be used to alter routing
210 parameters like throttling parameters.
212 \param[in] input Data source, object which controls
213 incoming data (connector or event)
214 \param[in] output Data target, object which controls
215 outgoing data (connector or event)
216 \returns Route instance describing this route
217 \see \ref ppi_throttling
218 \note The real implementation is not provided by three
219 overloads but by a single template member */
221 Route<connector::InputConnector, EventDescriptor> &
222 route(connector::InputConnector & input, EventDescriptor & output);
223 ///< Define flow information
224 /**< Route from a connector to an event. Routing from a
225 connector to an event defines the event as the
226 conceptual 'receiver' of the data. This means, the
227 event is controlling the processing of received data
228 packets (Example: Routing from an input to an IOEvent
229 defines, that input data will be processed whenever the
232 This event routing allows to automatically
233 enable/disable the event on throttling notifications.
237 Route<EventDescriptor, connector::OutputConnector> &
238 route(EventDescriptor & input, connector::OutputConnector & output);
239 ///< Define flow information
240 /**< Route from an event to a connector. Routing from an
241 event to a connector defines the event as the
242 conceptual 'source' of the data. This means, the event
243 controls how packets are sent (Example: Routing from an
244 IOEvent to an output defines, that output data will be
245 generated whenever the event is signaled).
247 This event routing allows to automatically
248 enable/disable the event on throttling notifications.
253 void noroute(connector::Connector & connector); ///< Define terminal connectors
254 /**< The noroute() member explicitly declares, that a
255 connector is terminal and does not directly
256 receive/forward data from/to some other
257 connector. <em>It is mandatory to define routing
258 information for terminal connectors</em>.
260 See the route() documentation for more on routing
262 \param[in] connector Terminal connector to declare */
265 template <class Descriptor, class Target>
266 void registerEvent(Descriptor & descriptor, Target target);
268 template <class Target>
269 void registerEvent(EventDescriptor & descriptor, Target target);
270 ///< Register an external event
271 /**< The \a target argument may be either an arbitrary
272 callable object or it may be a member function pointer
273 pointing to a member function of the Module derived
274 classed. The handler may \e optionally take an Argument
275 of type <tt>Descriptor::Event const &</tt>. This object
276 allows to access detailed information on the event
279 The \a descriptor describes the event to signal like a
280 timer event or some type of I/O event on a file
281 descriptor or socket.
283 \param[in] target The handler to call whenever the
285 \param[in] descriptor The type of event to register
286 \note The real implementation has the second arguments
287 type as an additional template parameter. */
290 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
291 /**< If available, this returns the scheduled time of the
294 ClockService::clock_type now() const; ///< Current time of the currently processing event
297 virtual void macro_SENF_PPI_MODULE_missing() = 0;
301 virtual void v_init(); ///< Called after module setup
302 /**< This member is called directly before the PPI (resumes)
303 execution. It is called after connections have been
304 setup before entering the PPI main loop.
306 You may overload this member. Your overload should
307 always call the base-class implementation. */
315 EventManager & eventManager() const;
316 ModuleManager & moduleManager() const;
318 void registerConnector(connector::Connector & connector);
319 void unregisterConnector(connector::Connector & connector);
320 void unregisterEvent(EventDescriptor & event);
322 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
324 typedef std::vector<connector::Connector *> ConnectorRegistry;
325 ConnectorRegistry connectorRegistry_;
327 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
328 RouteInfoBase routes_;
330 template <class Source, class Target>
331 friend class detail::RouteHelper;
332 friend class senf::ppi::ModuleManager;
333 friend class connector::Connector;
334 friend class senf::ppi::detail::EventBindingBase;
337 /** \brief Define PPI Module
339 Every module must begin by using this macro.
341 \see senf::ppi::module::Module
343 # define SENF_PPI_MODULE(name) \
345 ~ name() { destroy(); } \
346 void macro_SENF_PPI_MODULE_missing() {} \
351 ///////////////////////////////hh.e////////////////////////////////////////
352 #include "Module.cci"
354 //#include "Module.cti"
361 // c-file-style: "senf"
362 // indent-tabs-mode: nil
363 // ispell-local-dictionary: "american"
364 // compile-command: "scons -u test"
365 // comment-column: 40