b6407fbc36df8555fc7f6ac75f22c04d9f5cc8e3
[senf.git] / senf / PPI / Connectors.cci
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Connectors inline non-template implementation */
30
31 // Custom includes
32 #include <senf/Utils/TypeInfo.hh>
33 #include <senf/Utils/senfassert.hh>
34 #include "Module.hh"
35
36 #define prefix_ inline
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 #ifdef SENF_PPI_NOTRACE
40 #   define SENF_PPI_THROTTLE_TRACE(label, type)
41 #   define SENF_PPI_TRACE(packet, label)
42 #else
43 #   define SENF_PPI_THROTTLE_TRACE(label, type) throttleTrace(label, type)
44 #   define SENF_PPI_TRACE(packet, label) trace(packet, label)
45 #endif
46
47 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 // senf::ppi::connector::Connector
49
50 prefix_ senf::ppi::connector::Connector & senf::ppi::connector::Connector::peer()
51     const
52 {
53     // The connector is not connected
54     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
55     return *peer_;
56 }
57
58 prefix_ senf::ppi::module::Module & senf::ppi::connector::Connector::module()
59     const
60 {
61     // The connector is not registered in the module -> probably a route() or noroute() statement is
62     // missing.
63     SENF_ASSERT(module_, "Connector not registered: Missing route() or noroute()");
64     return *module_;
65 }
66
67 prefix_ void senf::ppi::connector::Connector::tracing(TraceState state)
68 {
69     traceState_ = state;
70 }
71
72 prefix_ senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::tracing()
73 {
74     return traceState_;
75 }
76
77 //-/////////////////////////////////////////////////////////////////////////////////////////////////
78 // protected members
79
80 prefix_ senf::ppi::connector::Connector::Connector()
81     : peer_(), module_()
82 {}
83
84 prefix_ bool senf::ppi::connector::Connector::connected()
85     const
86 {
87     return peer_;
88 }
89
90 //-/////////////////////////////////////////////////////////////////////////////////////////////////
91 // senf::ppi::connector::PassiveConnector
92
93 prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
94     const
95 {
96     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
97     return *peer_;
98 }
99
100 prefix_ bool senf::ppi::connector::PassiveConnector::throttled()
101     const
102 {
103     return nativeThrottled_ || remoteThrottled_;
104 }
105
106 //-/////////////////////////////////////////////////////////////////////////////////////////////////
107 // private members
108
109 prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
110 {
111     SENF_PPI_THROTTLE_TRACE("OUT", "throttle");
112     if (connected())
113         peer().notifyThrottle();
114 }
115
116 prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
117 {
118     SENF_PPI_THROTTLE_TRACE("OUT", "unthrottle");
119     if (connected()) {
120         peer().notifyUnthrottle();
121         v_unthrottleEvent();
122     }
123 }
124
125 prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
126 {
127     if (!throttled()) {
128         remoteThrottled_ = true;
129         emitThrottle();
130     }
131     else
132         remoteThrottled_ = true;
133 }
134
135 // public members
136
137 prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
138     const
139 {
140     return nativeThrottled_;
141 }
142
143 prefix_ void senf::ppi::connector::PassiveConnector::throttle()
144 {
145     if (!throttled()) {
146         nativeThrottled_ = true;
147         emitThrottle();
148     } else
149         nativeThrottled_ = true;
150 }
151
152 prefix_ void senf::ppi::connector::PassiveConnector::unthrottle()
153 {
154     if (throttled() && ! remoteThrottled_) {
155         nativeThrottled_ = false;
156         emitUnthrottle();
157     } else
158         nativeThrottled_ = false;
159
160 }
161
162 //-/////////////////////////////////////////////////////////////////////////////////////////////////
163 // protected members
164
165 prefix_ senf::ppi::connector::PassiveConnector::PassiveConnector()
166     : callback_(), remoteThrottled_(), nativeThrottled_()
167 {}
168
169 prefix_ void senf::ppi::connector::PassiveConnector::emit()
170 {
171     // No event callback has been registered (onRequest() call missing)
172     SENF_ASSERT(callback_, "senf::ppi::connector::PassiveConnector: missing onRequest()");
173     if (!throttled()) {
174         callback_();
175     } else {
176         SENF_PPI_THROTTLE_TRACE("IN ", "queueing packet");
177     }
178 }
179
180 //-/////////////////////////////////////////////////////////////////////////////////////////////////
181 // senf::ppi::connector::ActiveConnector
182
183 prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer()
184     const
185 {
186     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
187     return *peer_;
188 }
189
190 prefix_ void senf::ppi::connector::ActiveConnector::onThrottle()
191 {
192     throttleCallback_ = Callback();
193 }
194
195 prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle()
196 {
197     unthrottleCallback_ = Callback();
198 }
199
200 prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
201     const
202 {
203     return ! connected() || peer().throttled();
204 }
205
206 //-/////////////////////////////////////////////////////////////////////////////////////////////////
207 // protected members
208
209 prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector()
210     : throttleCallback_(), unthrottleCallback_(), notifyRoutes_(), throttled_(false)
211 {}
212
213 //-/////////////////////////////////////////////////////////////////////////////////////////////////
214 // senf::ppi::connector::InputConnector
215
216 prefix_ senf::Packet senf::ppi::connector::InputConnector::read()
217 {
218     return operator()();
219 }
220
221 prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer()
222     const
223 {
224     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
225     return *peer_;
226 }
227
228 prefix_ senf::ppi::connector::InputConnector::queue_iterator
229 senf::ppi::connector::InputConnector::begin()
230     const
231 {
232     return queue_.begin();
233 }
234
235 prefix_ senf::ppi::connector::InputConnector::queue_iterator
236 senf::ppi::connector::InputConnector::end()
237     const
238 {
239     return queue_.end();
240 }
241
242 prefix_ senf::Packet senf::ppi::connector::InputConnector::peek()
243     const
244 {
245     // Cannot peek() head of empty queue
246     SENF_ASSERT( ! queue_.empty(),
247                  "senf::ppi::connector::InputConnector: cannot call peek() on empty queue" );
248     return queue_.back();
249 }
250
251 prefix_ senf::ppi::connector::InputConnector::size_type
252 senf::ppi::connector::InputConnector::queueSize()
253     const
254 {
255     return queue_.size();
256 }
257
258 prefix_ bool senf::ppi::connector::InputConnector::empty()
259     const
260 {
261     return queue_.empty();
262 }
263
264 //-/////////////////////////////////////////////////////////////////////////////////////////////////
265 // protected members
266
267 prefix_ senf::ppi::connector::InputConnector::InputConnector()
268 {}
269
270 //-/////////////////////////////////////////////////////////////////////////////////////////////////
271 // private members
272
273 prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet const & p)
274 {
275     queue_.push_front(p);
276     v_enqueueEvent();
277 }
278
279 //-/////////////////////////////////////////////////////////////////////////////////////////////////
280 // senf::ppi::connector::OutputConnector
281
282 prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
283     const
284 {
285     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
286     return *peer_;
287 }
288
289 prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p)
290 {
291     SENF_PPI_TRACE(p, "OUT");
292     if (connected())
293         peer().enqueue(p);
294 }
295
296 prefix_ void senf::ppi::connector::OutputConnector::write(Packet const & p)
297 {
298     operator()(p);
299 }
300
301 //-/////////////////////////////////////////////////////////////////////////////////////////////////
302 // protected members
303
304 prefix_ senf::ppi::connector::OutputConnector::OutputConnector()
305 {}
306
307 //-/////////////////////////////////////////////////////////////////////////////////////////////////
308 // senf::ppi::connector::GenericPassiveInput
309
310 prefix_ senf::ppi::connector::GenericPassiveInput::GenericPassiveInput()
311     : qdisc_(new ThresholdQueueing(1,0))
312 {}
313
314 prefix_ senf::ppi::connector::GenericActiveOutput & senf::ppi::connector::GenericPassiveInput::peer()
315     const
316 {
317     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
318     return *peer_;
319 }
320
321 prefix_ bool senf::ppi::connector::GenericPassiveInput::boolean_test()
322     const
323 {
324     return ! empty();
325 }
326
327 //-/////////////////////////////////////////////////////////////////////////////////////////////////
328 // senf::ppi::connector::GenericPassiveOutput
329
330 prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connector::GenericPassiveOutput::peer()
331     const
332 {
333     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
334     return *peer_;
335 }
336
337 prefix_ bool senf::ppi::connector::GenericPassiveOutput::boolean_test()
338     const
339 {
340     return  true;
341 }
342
343 prefix_ void senf::ppi::connector::GenericPassiveOutput::connect(GenericActiveInput & target)
344 {
345     Connector::connect(target);
346 }
347
348 prefix_ senf::ppi::connector::GenericPassiveOutput::GenericPassiveOutput()
349 {}
350
351 //-/////////////////////////////////////////////////////////////////////////////////////////////////
352 // senf::ppi::connector::GenericActiveInput
353
354 prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::GenericActiveInput::peer()
355     const
356 {
357     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
358     return *peer_;
359 }
360
361 prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test()
362     const
363 {
364     return ! empty() || (connected() && ! peer().throttled());
365 }
366
367 prefix_ void senf::ppi::connector::GenericActiveInput::request()
368 {
369     if (connected())
370         peer().emit();
371 }
372
373 prefix_ senf::ppi::connector::GenericActiveInput::GenericActiveInput()
374 {}
375
376 //-/////////////////////////////////////////////////////////////////////////////////////////////////
377 // senf::ppi::connector::GenericActiveOutput
378
379 prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::GenericActiveOutput::peer()
380     const
381 {
382     SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
383     return *peer_;
384 }
385
386 prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test()
387     const
388 {
389     return connected() && ! peer().throttled();
390 }
391
392 prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target)
393 {
394     Connector::connect(target);
395 }
396
397 prefix_ senf::ppi::connector::GenericActiveOutput::GenericActiveOutput()
398 {}
399
400 //-/////////////////////////////////////////////////////////////////////////////////////////////////
401 #undef prefix_
402
403 \f
404 // Local Variables:
405 // mode: c++
406 // fill-column: 100
407 // comment-column: 40
408 // c-file-style: "senf"
409 // indent-tabs-mode: nil
410 // ispell-local-dictionary: "american"
411 // compile-command: "scons -u test"
412 // End: