Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief Conenctors public header */
/** \defgroup connectors Connector classes
A connector has two independent properties
\li it may be \e active or \e passive
\li it may be an \e input or an \e output
\e Active connectors are activated from within the module, \e passive connectors are signaled by
the external framework. \e Input modules receive packets, \e output modules send packets.
All passive connectors call some onRequest callback whenever I/O needs to be performed. All
input modules possess a packet queue.
We therefore have 4 connector types: senf::ppi::ActiveInput, senf::ppi::ActiveOutput,
senf::ppi::PassiveInput and senf::ppi::PassiveOutput.
*/
#ifndef HH_Conenctors_
#define HH_Conenctors_ 1
// Custom includes
#include <boost/utility.hpp>
//#include "Conenctors.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace ppi {
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/** \brief Connector baseclass
This connector provides access to the generic connector facilities. This includes the
connection management (access to the connected peer) and the containment management (access
to the containing module)
*/
class Connector
: boost::noncopyable
{
public:
Connector & peer(); ///< Get peer connected to this connector
Module & module(); ///< Get this connectors containing module
protected:
// here to protect
Connector();
~Connector();
};
/** \brief Passive connector baseclass
A passive connector is a connector which is activated externally whenever an I/O request
occurs. Passive connectors are the origin of throttling notifications. Depending on the type
of connector (output or input) the respective throttling is called forward or backward
throttling.
Passive connectors always handle two throttling states:
\li The \e native throttling state is set manually by the module. It is the throttling state
originating in the current module
\li The \e forwarded throttling state is the state as it is received by throttling
notifications
The accumulative throttling state is generated by combining all sub-states.
*/
class PassiveConnector
: public virtual Connector
{
public:
template <class Handler>
void onRequest(Handler handler);///< Register I/O event handler
/**< The registered handler will be called, whenever packets
arrive or should be generated by the module depending
on the connector type (input or output). The \a handler
argument is either an arbitrary callable object or it
is a pointer-to-member to a member of the class which
holds this input. In the second case, the pointer will
automatically be bound to the containing instance.
\param[in] handler Handler to call, whenever an I/O
operation is to be performed. */
bool throttled(); ///< Get accumulative throttling state
bool nativeThrottled(); ///< Get native throttling state
void throttle(); ///< Set native throttling
void unthrottle(); ///< Revoke native throttling
void notifyThrottle(); ///< Forward a throttling notification to this connector
void notifyUnthrottle(); ///< Forward an unthrottling notification to this connector
ActiveConnector & peer();
protected:
// here to protect
PassiveConnector();
~PassiveConnector();
};
/** \brief Active connector baseclass
An active connector is a connector which emits I/O requests. Active connectors receive
throttling notifications. Depending on the type of connector (input or output) the
respective throttling is called forward or backward throttling.
Active connectors do not handle any throttling state, they just receive the
notifications. These notifications should then either be processed by the module or be
forwarded to other connectors.
*/
class ActiveConnector
: public virtual Connector
{
public:
template <class Handler>
void onThrottle(Handler handle); ///< Register throttle notification handler
/**< The handler register here will be called, whenever a
throttle notification comes in. The \a handler argument
is either an arbitrary callable object or it is a
pointer-to-member to a member of the class which holds
this input. In the second case, the pointer will
automatically be bound to the containing instance.
notifications. */
template <class Handler>
void onUnthrottle(Handler handle); ///< Register unthrottle notification handler
/**< The handler register here will be called, whenever an
unthrottle notification comes in. The \a handler
argument is either an arbitrary callable object or it
is a pointer-to-member to a member of the class which
holds this input. In the second case, the pointer will
automatically be bound to the containing instance.
notifications. */
PassiveConnector & peer();
protected:
// here to protect
PassiveConnector();
~PassiveConnector();
};
/** \brief Input connector baseclass
An input connector receives packets. It may be either an ActiveConnector or a
PassiveConnector. An input connector contains a packet queue. This queue enables processing
packets in batches or generating multiple output packets from a single input packet. The
queues have the potential to greatly simplify the module implementations.
\implementation Which container to use?
\li list has good insertion and deletion properties on both ends but it costs a dynamic
memory allocation for every insertion. A very good property is, that iterators stay
valid across insertions/deletions
\li vector is fast and has good amortized dynamic allocation properties. However, it is
quite unusable as a queue
\li deque has comparable dynamic allocation properties as vector but also has good
insertion/removal properties on both ends.
So probably we will use a deque. I'd like a container which keeps iterators intact on
isertion/deletion but I believe that list is just to expensive since every packet will
be added to the queue before it can be processed.
*/
class InputConnector
: public virtual Connector
{
public:
typedef unspecified queue_iterator; ///< Iterator type of the embedded queue
typedef unspecified size_type; ///< Unsigned type representing the number of queue elements
Packet::ptr operator(); ///< Get a packet
/**< This member is the primary method to access received
data. On passive connectors, this operator will just
dequeue a packet from the packet queue. If the
connector is active, the connector will request new
packets from the connected module. If the packet
request cannot be fulfilled, this is considered to be a
logic error in the module implementation and an
exception is raised. */
operator unspecified_boolean_type (); ///< Check packet availability
/**< Using any input connector in a boolean context will
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
is always possible if the queue is non-empty. If the
input is active, it also returns when the connected
passive output is not throttled so new packets can be
requested.
Calling the operator() member is an error if this test
returns \c false
\returns \c true if operator() can be called, \c false
otherwise */
operator ! (); ///< Check packet availability
/**< Inverse of the boolean conversion operator
\returns \c false if operator() can be called, \c true
otherwise */
OutputConnector & peer();
queue_iterator begin(); ///< Access queue begin (head)
queue_iterator end(); ///< Access queue past-the-end (tail)
Packet::ptr head(); ///< Return head element from the queue
size_type queueSize(); ///< Return number of elements in the queue
bool empty(); ///< Return queueSize() == 0
protected:
// here to protect
PassiveConnector();
~PassiveConnector();
};
/** \brief Output connector baseclass
An output connector sends out packets. It may be either an ActiveConnector or a
PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
the queueing of the connected input.
*/
class OutputConnector
: public virtual Connector
{
public:
void operator(Packet::ptr); ///< Send out a packet
InputConnector & peer();
protected:
// here to protect
PassiveConnector();
~PassiveConnector();
};
/** \brief Combination of PassiveConnector and InputConnector
In addition to the native and the forwarded throttling state, the PassiveInput manages a
queue throttling state. This state is automatically managed by a queueing discipline. The
standard queueing discipline is ThresholdQueueing, which throttles the connection whenever
the queue length reaches the high threshold and unthrottles the connection when the queue
<tt>ThresholdQueueing(1,0)</tt> which will throttle the input whenever the queue is
non-empty.
*/
class PassiveInput
: public PassiveConnector, public InputConnector
{
public:
ActiveOutput & peer();
template <class QueueingDiscipline>
void qdisc(QueueingDiscipline const & disc); ///< Change the queueing discipline
/**< The queueing discipline is a class which provides the
QueueingDiscipline interface.
\param[in] disc New queueing discipline */
};
/** \brief Combination of PassiveConnector and OutputConnector
*/
class PassiveOutput
: public PassiveConnector, public OutputConnector
{
public:
ActiveInput & peer();
};
/** \brief Combination of ActiveConnector and InputConnector
*/
class ActiveInput
: public ActiveConnector, public InputConnector
{
public:
PassiveOutput & peer();
void request(); ///< request more packets without dequeuing any packet
};
/** \brief Combination of ActiveConnector and OutputConnector
*/
class ActiveOutput
: public ActiveConnector, public OutputConnector
{
public:
ActiveInput & peer();
};
///////////////////////////////hh.e////////////////////////////////////////
//#include "Conenctors.cci"
//#include "Conenctors.ct"
//#include "Conenctors.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"