Socket: Ignore ECONNREFUSED on write to datagram socket
[senf.git] / PPI / Module.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief Module public header 
23 */
24
25 #ifndef HH_Module_
26 #define HH_Module_ 1
27
28 // Custom includes
29 #include <vector>
30 #include <boost/utility.hpp>
31 #include <boost/ptr_container/ptr_vector.hpp>
32 #include "Scheduler/ClockService.hh"
33 #include "predecl.hh"
34
35 //#include "Module.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 namespace senf {
39 namespace ppi {
40 namespace module {
41
42     /** \namespace senf::ppi::module
43         \brief PPI Modules
44        
45         The modules build the PPI core. The PPI provides a set of general purpose infrastructure
46         modules. For concrete applications, additional application specific processing modules need
47         to be implemented.
48
49         \section module_impl Implementing Modules
50         
51         All modules derive from senf::ppi::module::Module. See this class for a documentation on how
52         to write new modules.
53
54         \section infrastructure_modules General Purpose Modules
55
56         The PPI provided general purpose modules can be grouped into several categories
57
58         \li \ref io_modules receive external data or forward packets out of the PPI
59         \li \ref sourcesink_modules generate or absorb packets internally
60         \li \ref routing_modules forward packets within the network
61         \li \ref adapter_modules are used to connect incompatible connectors to each other
62      */
63
64     /** \defgroup io_modules Input/Output Modules
65
66         Input/Output Modules receive data from external sources or forward data from the PPI to
67         outside targets.
68      */
69
70     /** \defgroup sourcesink_modules Source/Sink Modules
71
72         Source and Sink modules generate or absorb packets internally. In contrast to \ref
73         io_modules, they do not communicate outside the PPI.
74      */
75
76     /** \defgroup routing_modules Routing Modules
77
78         Routing modules perform packet forwarding within the network. They do not process the packet
79         data, they just route it.
80      */
81
82     /** \defgroup adapter_modules Adapter Modules
83
84         Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
85         active or passive connectors.
86      */
87
88     /** \brief Module base-class
89
90         senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
91         with interfaces to several PPI facilities:
92         
93         \li Connector management
94         \li Flow management (routing)
95         \li Event handling
96
97         To provide internal bookkeeping, most access to the PPI infrastructure is managed through
98         this base class. This is an example module specification:
99         \code
100         class SomeModule : public senf::ppi::module::Module
101         {
102             SENF_PPI_MODULE(SomeModule);
103
104             senf::FileHandle handle;
105
106             // If needed, define events
107             senf::ppi::IOEvent event;
108
109         public:
110             // Define connectors. Any number and type of connectors may be defined. Connectors
111             // must be public since they need to be accessed to connect modules with each other.
112             senf::ppi::connector::PassiveInput input;
113             senf::ppi::connector::ActiveOutput output;
114
115             SomeModule(senf::FileHandle h) 
116               : handle ( h ), 
117                 event  ( handle, senf::ppi::IOEvent::Read )
118             {
119                 // Set up routing. If some connector is not routed you need to explicitly state this
120                 // using noroute()
121                 route( input, output );
122                 route( event, output )
123                     .autoThrottling( false );
124
125                 // Register event handlers
126                 registerEvent( &SomeModule::read, event );
127
128                 // Register passive connector handlers
129                 input.onRequest( &SomeModule::outputRequest );
130
131                 // If needed, you may register throttling event handlers
132                 output.onThrottle( &SomeModule::throttle );
133                 output.onUnthrottle( &SomeModule::unthrottle );
134             }
135
136             void read() {
137                 // Called whenever the 'handle' is readable. Read data, do processing and so
138                 // on. This example reads the data, puts it into an ethernet packet and sends the
139                 // packet out via the active output.
140                 output(senf::EthernetPacket::create(handle.read()))
141             }
142
143             void outputRequest() {
144                 // Called whenever a packet is sent into the input to. Here we just forward it to
145                 // the output if it is an EthernetPacket
146                 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
147                 if (p)
148                     output(p);
149             }
150
151             void onThrottle() {
152                 // Called whenever a throttle notification comes in. Here, we just disable the
153                 // event (which is stupid since we should just not have disabled autoThrottling on
154                 // the route but this is only an example which tries to be simple ...)
155                 event.disable();
156             }
157
158             void onUnthrottle() {
159                 // and for unthrottle notifications
160                 event.enable();
161             }
162
163         };
164         \endcode
165
166         If your module only has a single input connector, you should call this connector \c
167         input. If it has only a single output connector, you should call it \c output. This allows
168         to setup connections without stating the connector explicitly (see senf::ppi::connect()).
169      */
170     class Module
171         : boost::noncopyable
172     {
173     public:
174         virtual ~Module();
175
176     protected:
177         Module();
178
179         template <class Source, class Target>
180         Route<Source, Target> & route(Source & source, Target & target); 
181                                         ///< Define flow information
182                                         /**< Using the route() and noroute() members, the
183                                              information flow within the module is defined. Routing
184                                              may be specified either between inputs, outputs and
185                                              events. The routing information is used to perform
186                                              automatic throttling. The throttling behavior may
187                                              however be controlled manually.
188
189                                              Even if no automatic throttling is desired <em>it is
190                                              vital to define the flow information for all inputs and
191                                              outputs</em>. Without flow information important
192                                              internal state of the module cannot be
193                                              initialized. This includes, explicitly defining
194                                              terminal inputs and outputs using noroute. Event
195                                              routing however is optional.
196
197                                              The return value may be used to alter routing
198                                              parameters like throttling parameters.
199                                              
200                                              \param[in] source Data source, object which controls
201                                                  incoming data
202                                              \param[in] target Data target, object which controls
203                                                  outgoing data
204                                              \returns Route instance describing this route */
205
206         void noroute(connector::Connector & connector); ///< Define terminal connectors
207                                         /**< The noroute() member explicitly declares, that a
208                                              connector is terminal and does not directly
209                                              receive/forward data from/to some other
210                                              connector. <em>It is mandatory to define routing
211                                              information for terminal connectors</em>.
212
213                                              See the route() documentation for more on routing
214                                              
215                                              \param[in] connector Terminal connector to declare */
216
217         template <class Target, class Descriptor>
218         void registerEvent(Target target, Descriptor & descriptor);
219                                         ///< Register an external event
220                                         /**< The \a target argument may be either an arbitrary
221                                              callable object or it may be a member function pointer
222                                              pointing to a member function of the Module derived
223                                              classed. The handler may \e optionally take an Argument
224                                              of type <tt>Descriptor::Event const &</tt>. This object
225                                              allows to access detailed information on the event
226                                              delivered.
227
228                                              The \a descriptor describes the event to signal. This
229
230                                              may be a timer event or some type of I/O event on a
231                                              file descriptor or socket.
232
233                                              \param[in] target The handler to call whenever the
234                                                  event is signaled
235                                              \param[in] descriptor The type of event to register */
236
237         ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
238                                         /**< If available, this returns the scheduled time of the
239                                              event. */
240
241         ClockService::clock_type now() const; ///< Current time of the currently processing event
242
243 #ifndef DOXYGEN
244         virtual void macro_SENF_PPI_MODULE_missing() = 0;
245 #endif
246
247 #ifndef DOXYGEN
248     private:
249 #endif
250         virtual void init();            ///< Called just before the network is run
251
252 #ifndef DOXYGEN
253     public:
254 #endif
255         void destroy();
256         
257     private:
258         EventManager & eventManager() const;
259         ModuleManager & moduleManager() const;
260         
261         void registerConnector(connector::Connector & connector);
262         RouteBase & addRoute(std::auto_ptr<RouteBase> route);
263
264         typedef std::vector<connector::Connector *> ConnectorRegistry;
265         ConnectorRegistry connectorRegistry_;
266
267         typedef boost::ptr_vector<RouteBase> RouteInfoBase;
268         RouteInfoBase routes_;
269
270         template <class Source, class Target>
271         friend class detail::RouteHelper;
272         friend class senf::ppi::ModuleManager;
273     };
274
275     /** \brief Define PPI Module
276
277         Every module must begin by using this macro. 
278
279         \see senf::ppi::module::Module
280      */
281 #   define SENF_PPI_MODULE(name)                                                                  \
282     public:                                                                                       \
283         ~ name() { destroy(); }                                                                   \
284         void macro_SENF_PPI_MODULE_missing() {}                                                   \
285     private:
286
287 }}}
288
289 ///////////////////////////////hh.e////////////////////////////////////////
290 #include "Module.cci"
291 #include "Module.ct"
292 //#include "Module.cti"
293 #endif
294
295 \f
296 // Local Variables:
297 // mode: c++
298 // fill-column: 100
299 // c-file-style: "senf"
300 // indent-tabs-mode: nil
301 // ispell-local-dictionary: "american"
302 // compile-command: "scons -u test"
303 // comment-column: 40
304 // End: