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
32 #include <boost/utility.hpp>
33 #include <boost/ptr_container/ptr_vector.hpp>
34 #include "../Scheduler/ClockService.hh"
36 #include "ModuleManager.hh"
38 //#include "Module.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
45 /** \namespace senf::ppi::module
48 The modules build the PPI core. The PPI provides a set of general purpose infrastructure
49 modules. For concrete applications, additional application specific processing modules need
52 \section module_impl Implementing Modules
54 All modules derive from senf::ppi::module::Module. See this class for a documentation on how
57 \section infrastructure_modules General Purpose Modules
59 The PPI provided general purpose modules can be grouped into several categories
61 \li \ref io_modules receive external data or forward packets out of the PPI
62 \li \ref routing_modules forward packets within the network
63 \li \ref adapter_modules are used to connect incompatible connectors to each other
65 \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
68 /** \defgroup io_modules Source/Sink Modules
70 Source and Sink modules generate or absorb packets in some way: Reading data from a file
71 descriptor, discarding packets etc.
74 /** \defgroup routing_modules Routing Modules
76 Routing modules perform packet forwarding within the network. They do not process the packet
77 data, they just route it.
80 /** \defgroup adapter_modules Adapter Modules
82 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
83 active or passive connectors.
86 /** \brief Module base-class
88 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
89 with interfaces to several PPI facilities:
91 \li Connector management
92 \li Flow management (routing)
95 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
96 this base class. This is an example module specification:
98 class SomeModule : public senf::ppi::module::Module
100 SENF_PPI_MODULE(SomeModule);
102 senf::FileHandle handle;
104 // If needed, define events
105 senf::ppi::IOEvent event;
108 // Define connectors. Any number and type of connectors may be defined. Connectors
109 // must be public since they need to be accessed to connect modules with each other.
110 senf::ppi::connector::PassiveInput<> input;
111 senf::ppi::connector::ActiveOutput<> output;
113 SomeModule(senf::FileHandle h)
115 event ( handle, senf::ppi::IOEvent::Read )
117 // Set up routing. If some connector is not routed you need to explicitly state this
119 route( input, output );
120 route( event, output )
121 .autoThrottling( false );
123 // Register event handlers
124 registerEvent( event, &SomeModule::read );
126 // Register passive connector handlers
127 input.onRequest( &SomeModule::outputRequest );
129 // If needed, you may register throttling event handlers
130 output.onThrottle( &SomeModule::throttle );
131 output.onUnthrottle( &SomeModule::unthrottle );
135 // Called whenever the 'handle' is readable. Read data, do processing and so
136 // on. This example reads the data, puts it into an ethernet packet and sends the
137 // packet out via the active output.
138 output(senf::EthernetPacket::create(handle.read()))
141 void outputRequest() {
142 // Called whenever a packet is sent into the input to. Here we just forward it to
143 // the output if it is an EthernetPacket
144 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
150 // Called whenever a throttle notification comes in. Here, we just disable the
151 // event (which is stupid since we should just not have disabled autoThrottling on
152 // the route but this is only an example which tries to be simple ...)
156 void onUnthrottle() {
157 // and for unthrottle notifications
164 If your module only has a single input connector, you should call this connector \c
165 input. If it has only a single output connector, you should call it \c output. This allows
166 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
168 \see \ref ppi_modules
171 : ModuleManager::Initializable, boost::noncopyable
180 template <class Source, class Target>
181 Route<Source, Target> & route(Source & source, Target & target);
183 Route<connector::InputConnector, connector::OutputConnector> &
184 route(connector::InputConnector & input, connector::OutputConnector & output);
185 ///< Define flow information
186 /**< Using the route() and noroute() members, the
187 information flow within the module is defined. Routing
188 may be defined between inputs, outputs and events. The
189 routing information is used to perform automatic
190 throttling. The throttling behavior may however be
193 Even if no automatic throttling is desired <em>it is
194 essential to define the flow information for all inputs
195 and outputs</em>. Without flow information important
196 internal state of the module cannot be
197 initialized. This includes, explicitly defining
198 terminal inputs and outputs using noroute. Event
199 routing is optional however.
201 The return value may be used to alter routing
202 parameters like throttling parameters.
204 \param[in] input Data source, object which controls
205 incoming data (connector or event)
206 \param[in] output Data target, object which controls
207 outgoing data (connector or event)
208 \returns Route instance describing this route
209 \see \ref ppi_throttling
210 \note The real implementation is not provided by three
211 overloads but by a single template member */
213 Route<connector::InputConnector, EventDescriptor> &
214 route(connector::InputConnector & input, EventDescriptor & output);
215 ///< Define flow information
216 /**< Route from a connector to an event. Routing from a
217 connector to an event defines the event as the
218 conceptual 'receiver' of the data. This means, the
219 event is controlling the processing of received data
220 packets (Example: Routing from an input to an IOEvent
221 defines, that input data will be processed whenever the
224 This event routing allows to automatically
225 enable/disable the event on throttling notifications.
229 Route<EventDescriptor, connector::OutputConnector> &
230 route(EventDescriptor & input, connector::OutputConnector & output);
231 ///< Define flow information
232 /**< Route from an event to a connector. Routing from an
233 event to a connector defines the event as the
234 conceptual 'source' of the data. This means, the event
235 controls how packets are sent (Example: Routing from an
236 IOEvent to an output defines, that output data will be
237 generated whenever the event is signaled).
239 This event routing allows to automatically
240 enable/disable the event on throttling notifications.
245 void noroute(connector::Connector & connector); ///< Define terminal connectors
246 /**< The noroute() member explicitly declares, that a
247 connector is terminal and does not directly
248 receive/forward data from/to some other
249 connector. <em>It is mandatory to define routing
250 information for terminal connectors</em>.
252 See the route() documentation for more on routing
254 \param[in] connector Terminal connector to declare */
257 template <class Descriptor, class Target>
258 void registerEvent(Descriptor & descriptor, Target target);
260 template <class Target>
261 void registerEvent(EventDescriptor & descriptor, Target target);
262 ///< Register an external event
263 /**< The \a target argument may be either an arbitrary
264 callable object or it may be a member function pointer
265 pointing to a member function of the Module derived
266 classed. The handler may \e optionally take an Argument
267 of type <tt>Descriptor::Event const &</tt>. This object
268 allows to access detailed information on the event
271 The \a descriptor describes the event to signal like a
272 timer event or some type of I/O event on a file
273 descriptor or socket.
275 \param[in] target The handler to call whenever the
277 \param[in] descriptor The type of event to register
278 \note The real implementation has the second arguments
279 type as an additional template parameter. */
282 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
283 /**< If available, this returns the scheduled time of the
286 ClockService::clock_type now() const; ///< Current time of the currently processing event
289 virtual void macro_SENF_PPI_MODULE_missing() = 0;
293 virtual void v_init();
301 EventManager & eventManager() const;
302 ModuleManager & moduleManager() const;
304 void registerConnector(connector::Connector & connector);
305 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
307 typedef std::vector<connector::Connector *> ConnectorRegistry;
308 ConnectorRegistry connectorRegistry_;
310 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
311 RouteInfoBase routes_;
313 template <class Source, class Target>
314 friend class detail::RouteHelper;
315 friend class senf::ppi::ModuleManager;
318 /** \brief Define PPI Module
320 Every module must begin by using this macro.
322 \see senf::ppi::module::Module
324 # define SENF_PPI_MODULE(name) \
326 ~ name() { destroy(); } \
327 void macro_SENF_PPI_MODULE_missing() {} \
332 ///////////////////////////////hh.e////////////////////////////////////////
333 #include "Module.cci"
335 //#include "Module.cti"
342 // c-file-style: "senf"
343 // indent-tabs-mode: nil
344 // ispell-local-dictionary: "american"
345 // compile-command: "scons -u test"
346 // comment-column: 40