PPI: Add simple connector type compatibility check
[senf.git] / PPI / Connectors.cci
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Connectors inline non-template implementation */
25
26 // Custom includes
27 #include "../Utils/TypeInfo.hh"
28 #include "../Utils/senfassert.hh"
29
30 #define prefix_ inline
31 ///////////////////////////////cci.p///////////////////////////////////////
32
33 ///////////////////////////////////////////////////////////////////////////
34 // senf::ppi::connector::Connector
35
36 prefix_ senf::ppi::connector::Connector & senf::ppi::connector::Connector::peer()
37     const
38 {
39     SENF_ASSERT(peer_);
40     return *peer_;
41 }
42
43 prefix_ senf::ppi::module::Module & senf::ppi::connector::Connector::module()
44     const
45 {
46     SENF_ASSERT(module_);
47     return *module_;
48 }
49
50 ////////////////////////////////////////
51 // protected members
52
53 prefix_ senf::ppi::connector::Connector::Connector()
54     : peer_(), module_()
55 {}
56
57 prefix_ senf::ppi::connector::Connector::~Connector()
58 {
59     if (peer_)
60         peer_->peer_ = 0;
61 }
62
63 ////////////////////////////////////////
64 // private members
65
66 prefix_ void senf::ppi::connector::Connector::setModule(module::Module & module)
67 {
68     module_ = &module;
69 }
70
71 ///////////////////////////////////////////////////////////////////////////
72 // senf::ppi::connector::PassiveConnector
73
74 prefix_ bool senf::ppi::connector::PassiveConnector::throttled()
75     const
76 {
77     return nativeThrottled_ || remoteThrottled_;
78 }
79
80 prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
81     const
82 {
83     return nativeThrottled_;
84 }
85
86 prefix_ void senf::ppi::connector::PassiveConnector::throttle()
87 {
88     if (!throttled()) {
89         nativeThrottled_ = true;
90         emitThrottle();
91     }
92 }
93
94 prefix_ void senf::ppi::connector::PassiveConnector::unthrottle()
95 {
96     if (throttled() && ! remoteThrottled_) {
97         nativeThrottled_ = false;
98         emitUnthrottle();
99     } else
100         nativeThrottled_ = false;
101
102 }
103
104 prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
105     const
106 {
107     return dynamic_cast<ActiveConnector&>(Connector::peer());
108 }
109
110 ////////////////////////////////////////
111 // protected members
112
113 prefix_ senf::ppi::connector::PassiveConnector::PassiveConnector()
114     : callback_(), remoteThrottled_(), nativeThrottled_()
115 {}
116
117 prefix_ void senf::ppi::connector::PassiveConnector::emit()
118 {
119     SENF_ASSERT(callback_);
120     if (!throttled())
121         callback_();
122 }
123
124 ////////////////////////////////////////
125 // private members
126
127 prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
128 {
129     if (!throttled()) {
130         remoteThrottled_ = true;
131         emitThrottle();
132     }
133     else
134         remoteThrottled_ = true;
135 }
136
137 prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
138 {
139     peer().notifyThrottle();
140 }
141
142 prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
143 {
144     peer().notifyUnthrottle();
145     v_unthrottleEvent();
146 }
147
148 prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
149 {}
150
151 prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
152 {
153     routes_.push_back(&route);
154 }
155
156 ///////////////////////////////////////////////////////////////////////////
157 // senf::ppi::connector::ActiveConnector
158
159 prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer()
160     const
161 {
162     return dynamic_cast<PassiveConnector&>(Connector::peer());
163 }
164
165 prefix_ void senf::ppi::connector::ActiveConnector::onThrottle()
166 {
167     throttleCallback_ = Callback();
168 }
169
170 prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle()
171 {
172     unthrottleCallback_ = Callback();
173 }
174
175 prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
176     const
177 {
178     return peer().throttled();
179 }
180
181 ////////////////////////////////////////
182 // protected members
183
184 prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector()
185     : throttleCallback_(), unthrottleCallback_(), notifyRoutes_()
186 {}
187
188 ///////////////////////////////////////////////////////////////////////////
189 // senf::ppi::connector::InputConnector
190
191 prefix_ senf::Packet senf::ppi::connector::InputConnector::read()
192 {
193     return operator()();
194 }
195
196 prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer()
197     const
198 {
199     return dynamic_cast<OutputConnector &>(Connector::peer());
200 }
201
202 prefix_ senf::ppi::connector::InputConnector::queue_iterator
203 senf::ppi::connector::InputConnector::begin()
204     const
205 {
206     return queue_.begin();
207 }
208
209 prefix_ senf::ppi::connector::InputConnector::queue_iterator
210 senf::ppi::connector::InputConnector::end()
211     const
212 {
213     return queue_.end();
214 }
215
216 prefix_ senf::Packet senf::ppi::connector::InputConnector::peek()
217     const
218 {
219     SENF_ASSERT( ! queue_.empty() );
220     return queue_.back();
221 }
222
223 prefix_ senf::ppi::connector::InputConnector::size_type
224 senf::ppi::connector::InputConnector::queueSize()
225     const
226 {
227     return queue_.size();
228 }
229
230 prefix_ bool senf::ppi::connector::InputConnector::empty()
231     const
232 {
233     return queue_.empty();
234 }
235
236 ////////////////////////////////////////
237 // protected members
238
239 prefix_ senf::ppi::connector::InputConnector::InputConnector()
240 {}
241
242 ////////////////////////////////////////
243 // private members
244
245 prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet p)
246 {
247     queue_.push_front(p);
248     v_enqueueEvent();
249 }
250
251 ///////////////////////////////////////////////////////////////////////////
252 // senf::ppi::connector::OutputConnector
253
254 prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet p)
255 {
256     peer().enqueue(p);
257 }
258
259 prefix_ void senf::ppi::connector::OutputConnector::write(Packet p)
260 {
261     operator()(p);
262 }
263
264 prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
265     const
266 {
267     return dynamic_cast<InputConnector&>(Connector::peer());
268 }
269
270 ////////////////////////////////////////
271 // protected members
272
273 prefix_ senf::ppi::connector::OutputConnector::OutputConnector()
274 {}
275
276 ///////////////////////////////////////////////////////////////////////////
277 // senf::ppi::connector::GenericPassiveInput
278
279 prefix_ senf::ppi::connector::GenericPassiveInput::GenericPassiveInput()
280     : qdisc_(new ThresholdQueueing(1,0))
281 {}
282
283 prefix_ senf::ppi::connector::GenericActiveOutput & senf::ppi::connector::GenericPassiveInput::peer()
284     const
285 {
286     return dynamic_cast<GenericActiveOutput&>(Connector::peer());
287 }
288
289 prefix_ bool senf::ppi::connector::GenericPassiveInput::boolean_test()
290     const
291 {
292     return ! empty();
293 }
294
295 ///////////////////////////////////////////////////////////////////////////
296 // senf::ppi::connector::GenericPassiveOutput
297
298 prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connector::GenericPassiveOutput::peer()
299     const
300 {
301     return dynamic_cast<GenericActiveInput&>(Connector::peer());
302 }
303
304 prefix_ bool senf::ppi::connector::GenericPassiveOutput::boolean_test()
305     const
306 {
307     return  true;
308 }
309
310 prefix_ void senf::ppi::connector::GenericPassiveOutput::connect(GenericActiveInput & target)
311 {
312     Connector::connect(target);
313 }
314
315 prefix_ senf::ppi::connector::GenericPassiveOutput::GenericPassiveOutput()
316 {}
317
318 ///////////////////////////////////////////////////////////////////////////
319 // senf::ppi::connector::GenericActiveInput
320
321 prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::GenericActiveInput::peer()
322     const
323 {
324     return dynamic_cast<GenericPassiveOutput&>(Connector::peer());
325 }
326
327 prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test()
328     const
329 {
330     return ! empty() || ! peer().throttled();
331 }
332
333 prefix_ void senf::ppi::connector::GenericActiveInput::request()
334 {
335     peer().emit();
336 }
337
338 prefix_ senf::ppi::connector::GenericActiveInput::GenericActiveInput()
339 {}
340
341 ///////////////////////////////////////////////////////////////////////////
342 // senf::ppi::connector::GenericActiveOutput
343
344 prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::GenericActiveOutput::peer()
345     const
346 {
347     return dynamic_cast<GenericPassiveInput&>(Connector::peer());
348 }
349
350 prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test()
351     const
352 {
353     return ! peer().throttled();
354 }
355
356 prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target)
357 {
358     Connector::connect(target);
359 }
360
361 prefix_ senf::ppi::connector::GenericActiveOutput::GenericActiveOutput()
362 {}
363
364 ///////////////////////////////cci.e///////////////////////////////////////
365 #undef prefix_
366
367 \f
368 // Local Variables:
369 // mode: c++
370 // fill-column: 100
371 // comment-column: 40
372 // c-file-style: "senf"
373 // indent-tabs-mode: nil
374 // ispell-local-dictionary: "american"
375 // compile-command: "scons -u test"
376 // End: