2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
22 \brief Connectors public header */
24 /** \defgroup connectors Connector classes
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
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.
33 All passive connectors call some onRequest callback whenever I/O needs to be performed. All
34 input modules possess a packet queue.
36 We therefore have 4 connector types: senf::ppi::ActiveInput, senf::ppi::ActiveOutput,
37 senf::ppi::PassiveInput and senf::ppi::PassiveOutput.
40 #ifndef HH_Connectors_
41 #define HH_Connectors_ 1
45 #include <boost/utility.hpp>
46 #include <boost/scoped_ptr.hpp>
47 #include "Utils/SafeBool.hh"
48 #include "Packets/Packets.hh"
50 #include "detail/Callback.hh"
51 #include "Queueing.hh"
53 //#include "Connectors.mpp"
54 ///////////////////////////////hh.p////////////////////////////////////////
60 /** \brief Connector baseclass
62 This connector provides access to the generic connector facilities. This includes the
63 connection management (access to the connected peer) and the containment management (access
64 to the containing module)
70 Connector & peer() const; ///< Get peer connected to this connector
71 module::Module & module() const; ///< Get this connectors containing module
77 void connect(Connector & target);
80 void setModule(module::Module & module);
83 module::Module * module_;
85 friend class module::Module;
88 /** \brief Passive connector baseclass
90 A passive connector is a connector which is activated externally whenever an I/O request
91 occurs. Passive connectors are the origin of throttling notifications. Depending on the type
92 of connector (output or input) the respective throttling is called forward or backward
95 Passive connectors always handle two throttling states:
97 \li The \e native throttling state is set manually by the module. It is the throttling state
98 originating in the current module
99 \li The \e forwarded throttling state is the state as it is received by throttling
102 The accumulative throttling state is generated by combining all sub-states.
104 class PassiveConnector
105 : public virtual Connector
108 template <class Handler>
109 void onRequest(Handler handler);///< Register I/O event handler
110 /**< The registered handler will be called, whenever packets
111 arrive or should be generated by the module depending
112 on the connector type (input or output). The \a handler
113 argument is either an arbitrary callable object or it
114 is a pointer-to-member to a member of the class which
115 holds this input. In the second case, the pointer will
116 automatically be bound to the containing instance.
118 \param[in] handler Handler to call, whenever an I/O
119 operation is to be performed. */
122 bool throttled() const; ///< Get accumulative throttling state
123 bool nativeThrottled() const; ///< Get native throttling state
125 void throttle(); ///< Set native throttling
126 void unthrottle(); ///< Revoke native throttling
128 ActiveConnector & peer() const;
136 // Called by the routing to change the remote throttling state
137 void notifyThrottle(); ///< Forward a throttling notification to this connector
138 void notifyUnthrottle(); ///< Forward an unthrottling notification to this connector
140 // Internal members to emit throttling notifications
142 void emitUnthrottle();
144 // Called after unthrottling the connector
145 virtual void v_unthrottleEvent();
147 // called by ForwardingRoute to register a new route
148 void registerRoute(ForwardingRoute & route);
150 typedef detail::Callback<>::type Callback;
153 bool remoteThrottled_;
154 bool nativeThrottled_;
156 typedef std::vector<ForwardingRoute*> Routes;
159 friend class senf::ppi::ForwardingRoute;
162 /** \brief Active connector baseclass
164 An active connector is a connector which emits I/O requests. Active connectors receive
165 throttling notifications. Depending on the type of connector (input or output) the
166 respective throttling is called forward or backward throttling.
168 Active connectors do not handle any throttling state, they just receive the
169 notifications. These notifications should then either be processed by the module or be
170 forwarded to other connectors.
172 class ActiveConnector
173 : public virtual Connector
175 typedef detail::Callback<>::type Callback;
177 template <class Handler>
178 void onThrottle(Handler handler); ///< Register throttle notification handler
179 /**< The handler register here will be called, whenever a
180 throttle notification comes in. The \a handler argument
181 is either an arbitrary callable object or it is a
182 pointer-to-member to a member of the class which holds
183 this input. In the second case, the pointer will
184 automatically be bound to the containing instance.
186 \param[in] handler Handler to call on throttle
188 void onThrottle(); ///< Clear throttle notification handler
190 template <class Handler>
191 void onUnthrottle(Handler handler); ///< Register unthrottle notification handler
192 /**< The handler register here will be called, whenever an
193 unthrottle notification comes in. The \a handler
194 argument is either an arbitrary callable object or it
195 is a pointer-to-member to a member of the class which
196 holds this input. In the second case, the pointer will
197 automatically be bound to the containing instance.
199 \param[in] handle Handler to call on unthrottle
201 void onUnthrottle(); ///< Clear unthrottle notification handler
203 bool throttled() const; ///< \c true, if peer() is throttled
205 PassiveConnector & peer() const;
211 // called by the peer() to forward throttling notifications
212 void notifyThrottle();
213 void notifyUnthrottle();
215 // called by ForwardingRoute to register a new route
216 void registerRoute(ForwardingRoute & route);
218 Callback throttleCallback_;
219 Callback unthrottleCallback_;
221 typedef std::vector<ForwardingRoute*> NotifyRoutes;
222 NotifyRoutes notifyRoutes_;
224 friend class senf::ppi::ForwardingRoute;
225 friend class PassiveConnector;
228 /** \brief Input connector baseclass
230 An input connector receives packets. It may be either an ActiveConnector or a
231 PassiveConnector. An input connector contains a packet queue. This queue enables processing
232 packets in batches or generating multiple output packets from a single input packet. The
233 queues have the potential to greatly simplify the module implementations.
235 \implementation Which container to use?
236 \li list has good insertion and deletion properties on both ends but it costs a dynamic
237 memory allocation for every insertion. A very good property is, that iterators stay
238 valid across insertions/deletions
239 \li vector is fast and has good amortized dynamic allocation properties. However, it is
240 quite unusable as a queue
241 \li deque has comparable dynamic allocation properties as vector but also has good
242 insertion/removal properties on both ends.
244 So probably we will use a deque. I'd like a container which keeps iterators intact on
245 isertion/deletion but I believe that list is just to expensive since every packet will
246 be added to the queue before it can be processed.
249 : public virtual Connector
251 typedef std::deque<Packet> Queue;
253 typedef Queue::const_iterator queue_iterator; ///< Iterator type of the embedded queue
254 typedef Queue::size_type size_type; ///< Unsigned type for counting queue elements
256 Packet operator()(); ///< Get a packet
257 /**< This member is the primary method to access received
258 data. On passive connectors, this operator will just
259 dequeue a packet from the packet queue. If the
260 connector is active, the connector will request new
261 packets from the connected module. If the packet
262 request cannot be fulfilled, this is considered to be a
263 logic error in the module implementation and an
264 exception is raised. */
266 OutputConnector & peer() const;
268 queue_iterator begin() const; ///< Access queue begin (head)
269 queue_iterator end() const; ///< Access queue past-the-end (tail)
270 Packet peek() const; ///< Return head element from the queue
272 size_type queueSize() const; ///< Return number of elements in the queue
273 bool empty() const; ///< Return queueSize() == 0
279 void enqueue(Packet p);
281 virtual void v_requestEvent();
282 virtual void v_enqueueEvent();
283 virtual void v_dequeueEvent();
287 friend class OutputConnector;
290 /** \brief Output connector baseclass
292 An output connector sends out packets. It may be either an ActiveConnector or a
293 PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
294 the queueing of the connected input.
296 class OutputConnector
297 : public virtual Connector
300 void operator()(Packet p); ///< Send out a packet
302 InputConnector & peer() const;
309 ///\addtogroup connectors
311 /** \brief Combination of PassiveConnector and InputConnector
313 The PassiveInput automatically controls the connectors throttling state using a queueing
314 discipline. The standard queueing discipline is ThresholdQueueing, which throttles the
315 connection whenever the queue length reaches the high threshold and unthrottles the
316 connection when the queue reaches the low threshold. The default queueing discipline is
317 <tt>ThresholdQueueing(1,0)</tt> which will throttle the input whenever the queue is
321 : public PassiveConnector, public InputConnector,
322 public SafeBool<PassiveInput>
327 ActiveOutput & peer() const;
329 bool boolean_test() const; ///< \c true, if ! empty()
331 template <class QDisc>
332 void qdisc(QDisc const & disc); ///< Change the queueing discipline
333 /**< The queueing discipline is a class which provides the
334 QueueingDiscipline interface.
336 \param[in] disc New queueing discipline */
339 void v_enqueueEvent();
340 void v_dequeueEvent();
341 void v_unthrottleEvent();
343 boost::scoped_ptr<QueueingDiscipline> qdisc_;
346 /** \brief Combination of PassiveConnector and OutputConnector
349 : public PassiveConnector, public OutputConnector,
350 public SafeBool<PassiveOutput>
353 ActiveInput & peer() const;
355 bool boolean_test() const; ///< Always \c true
357 void connect(ActiveInput & target); ///< Internal: Use senf::ppi::connect() instead
359 friend class ActiveInput;
362 /** \brief Combination of ActiveConnector and InputConnector
365 : public ActiveConnector, public InputConnector,
366 public SafeBool<ActiveInput>
369 PassiveOutput & peer() const;
371 bool boolean_test() const; ///< \c true, if ! empty() or ! throttled()
373 void request(); ///< request more packets without dequeuing any packet
376 void v_requestEvent();
379 /** \brief Combination of ActiveConnector and OutputConnector
382 : public ActiveConnector, public OutputConnector,
383 public SafeBool<ActiveOutput>
386 PassiveInput & peer() const;
388 bool boolean_test() const; ///< \c true if peer() is ! throttled()
390 void connect(PassiveInput & target); ///< Internal: Use senf::ppi::connect() instead
397 ///////////////////////////////hh.e////////////////////////////////////////
398 #include "Connectors.cci"
399 //#include "Connectors.ct"
400 #include "Connectors.cti"
407 // c-file-style: "senf"
408 // indent-tabs-mode: nil
409 // ispell-local-dictionary: "american"
410 // compile-command: "scons -u test"
411 // comment-column: 40