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////////////////////////////////////////
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
66 /** \defgroup io_modules Source/Sink Modules
68 Source and Sink modules generate or absorb packets in some way: Reading data from a file
69 descriptor, discarding packets etc.
72 /** \defgroup routing_modules Routing Modules
74 Routing modules perform packet forwarding within the network. They do not process the packet
75 data, they just route it.
78 /** \defgroup adapter_modules Adapter Modules
80 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
81 active or passive connectors.
84 /** \brief Module base-class
86 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
87 with interfaces to several PPI facilities:
89 \li Connector management
90 \li Flow management (routing)
93 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
94 this base class. This is an example module specification:
96 class SomeModule : public senf::ppi::module::Module
98 SENF_PPI_MODULE(SomeModule);
100 senf::FileHandle handle;
102 // If needed, define events
103 senf::ppi::IOEvent event;
106 // Define connectors. Any number and type of connectors may be defined. Connectors
107 // must be public since they need to be accessed to connect modules with each other.
108 senf::ppi::connector::PassiveInput<> input;
109 senf::ppi::connector::ActiveOutput<> output;
111 SomeModule(senf::FileHandle h)
113 event ( handle, senf::ppi::IOEvent::Read )
115 // Set up routing. If some connector is not routed you need to explicitly state this
117 route( input, output );
118 route( event, output )
119 .autoThrottling( false );
121 // Register event handlers
122 registerEvent( event, &SomeModule::read );
124 // Register passive connector handlers
125 input.onRequest( &SomeModule::outputRequest );
127 // If needed, you may register throttling event handlers
128 output.onThrottle( &SomeModule::throttle );
129 output.onUnthrottle( &SomeModule::unthrottle );
133 // Called whenever the 'handle' is readable. Read data, do processing and so
134 // on. This example reads the data, puts it into an ethernet packet and sends the
135 // packet out via the active output.
136 output(senf::EthernetPacket::create(handle.read()))
139 void outputRequest() {
140 // Called whenever a packet is sent into the input to. Here we just forward it to
141 // the output if it is an EthernetPacket
142 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
148 // Called whenever a throttle notification comes in. Here, we just disable the
149 // event (which is stupid since we should just not have disabled autoThrottling on
150 // the route but this is only an example which tries to be simple ...)
154 void onUnthrottle() {
155 // and for unthrottle notifications
160 // Optional. Called after before running the module but after connections have been
161 // set up. This is either directly before senf::ppi::run() or senf::ppi::init() is
162 // called or, for modules created while the PPI is already running, after returning
163 // from all event handlers but before going back to the event loop.
169 If your module only has a single input connector, you should call this connector \c
170 input. If it has only a single output connector, you should call it \c output. This allows
171 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
173 \see \ref ppi_modules
176 : ModuleManager::Initializable, boost::noncopyable
185 template <class Source, class Target>
186 Route<Source, Target> & route(Source & source, Target & target);
188 Route<connector::InputConnector, connector::OutputConnector> &
189 route(connector::InputConnector & input, connector::OutputConnector & output);
190 ///< Define flow information
191 /**< Using the route() and noroute() members, the
192 information flow within the module is defined. Routing
193 may be defined between inputs, outputs and events. The
194 routing information is used to perform automatic
195 throttling. The throttling behavior may however be
198 Even if no automatic throttling is desired <em>it is
199 essential to define the flow information for all inputs
200 and outputs</em>. Without flow information important
201 internal state of the module cannot be
202 initialized. This includes, explicitly defining
203 terminal inputs and outputs using noroute. Event
204 routing is optional however.
206 The return value may be used to alter routing
207 parameters like throttling parameters.
209 \param[in] input Data source, object which controls
210 incoming data (connector or event)
211 \param[in] output Data target, object which controls
212 outgoing data (connector or event)
213 \returns Route instance describing this route
214 \see \ref ppi_throttling
215 \note The real implementation is not provided by three
216 overloads but by a single template member */
218 Route<connector::InputConnector, EventDescriptor> &
219 route(connector::InputConnector & input, EventDescriptor & output);
220 ///< Define flow information
221 /**< Route from a connector to an event. Routing from a
222 connector to an event defines the event as the
223 conceptual 'receiver' of the data. This means, the
224 event is controlling the processing of received data
225 packets (Example: Routing from an input to an IOEvent
226 defines, that input data will be processed whenever the
229 This event routing allows to automatically
230 enable/disable the event on throttling notifications.
234 Route<EventDescriptor, connector::OutputConnector> &
235 route(EventDescriptor & input, connector::OutputConnector & output);
236 ///< Define flow information
237 /**< Route from an event to a connector. Routing from an
238 event to a connector defines the event as the
239 conceptual 'source' of the data. This means, the event
240 controls how packets are sent (Example: Routing from an
241 IOEvent to an output defines, that output data will be
242 generated whenever the event is signaled).
244 This event routing allows to automatically
245 enable/disable the event on throttling notifications.
250 void noroute(connector::Connector & connector); ///< Define terminal connectors
251 /**< The noroute() member explicitly declares, that a
252 connector is terminal and does not directly
253 receive/forward data from/to some other
254 connector. <em>It is mandatory to define routing
255 information for terminal connectors</em>.
257 See the route() documentation for more on routing
259 \param[in] connector Terminal connector to declare */
262 template <class Descriptor, class Target>
263 void registerEvent(Descriptor & descriptor, Target target);
265 template <class Target>
266 void registerEvent(EventDescriptor & descriptor, Target target);
267 ///< Register an external event
268 /**< The \a target argument may be either an arbitrary
269 callable object or it may be a member function pointer
270 pointing to a member function of the Module derived
271 classed. The handler may \e optionally take an Argument
272 of type <tt>Descriptor::Event const &</tt>. This object
273 allows to access detailed information on the event
276 The \a descriptor describes the event to signal like a
277 timer event or some type of I/O event on a file
278 descriptor or socket.
280 \param[in] target The handler to call whenever the
282 \param[in] descriptor The type of event to register
283 \note The real implementation has the second arguments
284 type as an additional template parameter. */
287 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
288 /**< If available, this returns the scheduled time of the
291 ClockService::clock_type now() const; ///< Current time of the currently processing event
294 virtual void macro_SENF_PPI_MODULE_missing() = 0;
298 virtual void v_init(); ///< Called after module setup
299 /**< This member is called directly before the PPI (resumes)
300 execution. It is called after connections have been
301 setup before entering the PPI main loop.
303 You may overload this member. Your overload should
304 always call the base-class implementation. */
312 EventManager & eventManager() const;
313 ModuleManager & moduleManager() const;
315 void registerConnector(connector::Connector & connector);
316 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
318 typedef std::vector<connector::Connector *> ConnectorRegistry;
319 ConnectorRegistry connectorRegistry_;
321 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
322 RouteInfoBase routes_;
324 template <class Source, class Target>
325 friend class detail::RouteHelper;
326 friend class senf::ppi::ModuleManager;
329 /** \brief Define PPI Module
331 Every module must begin by using this macro.
333 \see senf::ppi::module::Module
335 # define SENF_PPI_MODULE(name) \
337 ~ name() { destroy(); } \
338 void macro_SENF_PPI_MODULE_missing() {} \
343 ///////////////////////////////hh.e////////////////////////////////////////
344 #include "Module.cci"
346 //#include "Module.cti"
353 // c-file-style: "senf"
354 // indent-tabs-mode: nil
355 // ispell-local-dictionary: "american"
356 // compile-command: "scons -u test"
357 // comment-column: 40