PPI Module and Connector documentation
[senf.git] / PPI / Connectors.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 Conenctors public header */
23
24 /** \defgroup connectors Connector classes
25
26     A connector has two independent properties
27     \li it may be \e active or \e passive
28     \li it may be an \e input or an \e output
29     
30     \e Active connectors are activated from within the module, \e passive connectors are signaled by
31     the external framework. \e Input modules receive packets, \e output modules send packets.
32
33     All passive connectors call some onRequest callback whenever I/O needs to be performed. All
34     input modules possess a packet queue.
35
36     We therefore have 4 connector types: senf::ppi::ActiveInput, senf::ppi::ActiveOutput,
37     senf::ppi::PassiveInput and senf::ppi::PassiveOutput.
38  */
39
40 #ifndef HH_Conenctors_
41 #define HH_Conenctors_ 1
42
43 // Custom includes
44 #include <boost/utility.hpp>
45
46 //#include "Conenctors.mpp"
47 ///////////////////////////////hh.p////////////////////////////////////////
48
49 namespace senf {
50 namespace ppi {
51
52     /** \brief Connector baseclass
53
54         This connector provides access to the generic connector facilities. This includes the
55         connection management (access to the connected peer) and the containment management (access
56         to the containing module)
57      */
58     class Connector
59         : boost::noncopyable
60     {
61     public:
62         Connector & peer();             ///< Get peer connected to this connector
63         Module & module();              ///< Get this connectors containing module
64
65     protected:
66         // here to protect
67         Connector();
68         ~Connector();
69     };
70
71     /** \brief Passive connector baseclass
72
73         A passive connector is a connector which is activated externally whenever an I/O request
74         occurs. Passive connectors are the origin of throttling notifications. Depending on the type
75         of connector (output or input) the respective throttling is called forward or backward
76         throttling.
77
78         Passive connectors always handle two throttling states: 
79         
80         \li The \e native throttling state is set manually by the module. It is the throttling state
81             originating in the current module
82         \li The \e forwarded throttling state is the state as it is received by throttling
83             notifications
84
85         The accumulative throttling state is generated by combining all sub-states.
86
87         \ingroup connectors
88      */
89     class PassiveConnector 
90         : public virtual Connector
91     {
92     public:
93         template <class Handler>
94         void onRequest(Handler handler);///< Register I/O event handler
95                                         /**< The registered handler will be called, whenever packets
96                                              arrive or should be generated by the module depending
97                                              on the connector type (input or output). The \a handler
98                                              argument is either an arbitrary callable object or it
99                                              is a pointer-to-member to a member of the class which
100                                              holds this input. In the second case, the pointer will
101                                              automatically be bound to the containing instance.
102                                              
103                                              \param[in] handler Handler to call, whenever an I/O
104                                                  operation is to be performed. */
105
106         
107         bool throttled();               ///< Get accumulative throttling state
108         bool nativeThrottled();         ///< Get native throttling state
109
110         void throttle();                ///< Set native throttling
111         void unthrottle();              ///< Revoke native throttling
112         
113         void notifyThrottle();          ///< Forward a throttling notification to this connector
114         void notifyUnthrottle();        ///< Forward an unthrottling notification to this connector
115
116         ActiveConnector & peer();
117
118     protected:
119         // here to protect
120         PassiveConnector();
121         ~PassiveConnector();
122     };
123
124     /** \brief Active connector baseclass
125
126         An active connector is a connector which emits I/O requests. Active connectors receive
127         throttling notifications. Depending on the type of connector (input or output) the
128         respective throttling is called forward or backward throttling.
129
130         Active connectors do not handle any throttling state, they just receive the
131         notifications. These notifications should then either be processed by the module or be
132         forwarded to other connectors.
133
134         \ingroup connectors
135      */
136     class ActiveConnector 
137         : public virtual Connector
138     {
139     public:
140         template <class Handler>
141         void onThrottle(Handler);       ///< Register throttle notification handler
142                                         /**< The handler register here will be called, whenever a
143                                              throttle notification comes in. The \a handler argument
144                                              is either an arbitrary callable object or it is a
145                                              pointer-to-member to a member of the class which holds
146                                              this input. In the second case, the pointer will
147                                              automatically be bound to the containing instance.
148
149                                              \param[in] handler Handler to call on throttle
150                                                  notifications. */
151
152         template <class Handler>
153         void onUnthrottle(Handler);     ///< Register unthrottle notification handler
154                                         /**< The handler register here will be called, whenever an
155                                              unthrottle notification comes in. The \a handler
156                                              argument is either an arbitrary callable object or it
157                                              is a pointer-to-member to a member of the class which
158                                              holds this input. In the second case, the pointer will
159                                              automatically be bound to the containing instance.
160
161                                              \param[in] handler Handler to call on unthrottle
162                                                  notifications. */
163
164         PassiveConnector & peer();
165
166     protected:
167         // here to protect
168         PassiveConnector();
169         ~PassiveConnector();
170     };
171
172     /** \brief Input connector baseclass
173
174         An input connector receives packets. It may be either an ActiveConnector or a
175         PassiveConnector. An input connector contains a packet queue. This queue enables processing
176         packets in batches or generating multiple output packets from a single input packet. The
177         queues have the potential to greatly simplify the module implementations.
178
179         \ingroup connectors
180      */
181     class InputConnector 
182         : public virtual Connector
183     {
184     public:
185         typedef unspecified queue_iterator; ///< Iterator type of the embedded queue
186         typedef unspecified size_type;  ///< Unsigned type representing the number of queue elements
187
188         Packet::ptr operator();         ///< Get a packet
189                                         /**< This member is the primary method to access received
190                                              data. On passive connectors, this operator will just
191                                              dequeue a packet from the packet queue. If the
192                                              connector is active, the connector will request new
193                                              packets from the connected module. If the packet
194                                              request cannot be fulfilled, this is considered to be a
195                                              logic error in the module implementation and an
196                                              exception is raised. */
197         operator unspecified_boolean_type (); ///< Check packet availability
198                                         /**< Using any input connector in a boolean context will
199                                              check, wether an input request can be fulfilled. This
200                                              is always possible if the queue is non-empty. If the
201                                              input is active, it also returns when the connected
202                                              passive output is not throttled so new packets can be
203                                              requested. 
204
205                                              Calling the operator() member is an error if this test
206                                              returns \c false
207
208                                              \returns \c true if operator() can be called, \c false
209                                                  otherwise */
210         operator ! ();                  ///< Check packet availability
211                                         /**< Inverse of the boolean conversion operator
212                                              \returns \c false if operator() can be called, \c true
213                                                  otherwise */
214
215         OutputConnector & peer();
216
217         queue_iterator begin();         ///< Access queue begin (head)
218         queue_iterator end();           ///< Access queue past-the-end (tail)
219         Packet::ptr head();             ///< Return head element from the queue
220
221         size_type queueSize();          ///< Return number of elements in the queue
222         bool empty();                   ///< Return queueSize() == 0
223
224     protected:
225         // here to protect
226         PassiveConnector();
227         ~PassiveConnector();
228     };
229     
230     /** \brief Output connector baseclass
231         
232         An output connector sends out packets. It may be either an ActiveConnector or a
233         PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
234         the queueing of the connected input.
235
236         \ingroup connectors
237      */
238     class OutputConnector 
239         : public virtual Connector
240     {
241     public:
242         void operator(Packet::ptr);     ///< Send out a packet
243
244         InputConnector & peer();
245
246     protected:
247         // here to protect
248         PassiveConnector();
249         ~PassiveConnector();
250     };
251
252     /** \brief Combination of PassiveConnector and InputConnector
253
254         \ingroup connectors
255      */
256     class PassiveInput 
257         : public PassiveConnector, public InputConnector
258     {
259     public:
260         ActiveOutput & peer();
261
262         template <class QDisc>
263         QDisc const & qdisc(QDisc const & disc);
264     };
265
266     /** \brief Combination of PassiveConnector and OutputConnector
267
268         \ingroup connectors
269      */
270     class PassiveOutput
271         : public PassiveConnector, public OutputConnector
272     {
273     public:
274         ActiveInput & peer();
275     };
276
277     /** \brief Combination of ActiveConnector and InputConnector
278
279         \ingroup connectors
280      */
281     class ActiveInput
282         : public ActiveConnector, public InputConnector
283     {
284     public:
285         void request();                 ///< request more packets without dequeing any packet
286
287         PassiveOutput & peer();
288     };
289
290     /** \brief Combination of ActiveConnector and OutputConnector
291
292         \ingroup connectors
293      */
294     class ActiveOutput
295         : public ActiveConnector, public OutputConnector
296     {
297     public:
298         ActiveInput & peer();
299     };
300
301 }}
302
303 ///////////////////////////////hh.e////////////////////////////////////////
304 //#include "Conenctors.cci"
305 //#include "Conenctors.ct"
306 //#include "Conenctors.cti"
307 #endif
308
309 \f
310 // Local Variables:
311 // mode: c++
312 // fill-column: 100
313 // c-file-style: "senf"
314 // indent-tabs-mode: nil
315 // ispell-local-dictionary: "american"
316 // End: