1f3f192259d2e67ac27b6dc0f8ebb75334a07c06
[senf.git] / PPI / Connectors.cci
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
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
28 #define prefix_ inline
29 ///////////////////////////////cci.p///////////////////////////////////////
30
31 ///////////////////////////////////////////////////////////////////////////
32 // senf::ppi::connector::Connector
33
34 prefix_ senf::ppi::connector::Connector & senf::ppi::connector::Connector::peer()
35     const
36 {
37     BOOST_ASSERT(peer_);
38     return *peer_;
39 }
40
41 prefix_ senf::ppi::module::Module & senf::ppi::connector::Connector::module()
42     const
43 {
44     BOOST_ASSERT(module_);
45     return *module_;
46 }
47
48 ////////////////////////////////////////
49 // protected members
50
51 prefix_ senf::ppi::connector::Connector::Connector()
52     : peer_(), module_()
53 {}
54
55 prefix_ senf::ppi::connector::Connector::~Connector()
56 {
57     if (peer_)
58         peer_->peer_ = 0;
59 }
60
61 prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
62 {
63     peer_ = & target;
64     target.peer_ = this;
65 }
66
67 ////////////////////////////////////////
68 // private members
69
70 prefix_ void senf::ppi::connector::Connector::setModule(module::Module & module)
71 {
72     module_ = &module;
73 }
74
75 ///////////////////////////////////////////////////////////////////////////
76 // senf::ppi::connector::PassiveConnector
77
78 prefix_ bool senf::ppi::connector::PassiveConnector::throttled()
79     const
80 {
81     return nativeThrottled_ || remoteThrottled_;
82 }
83
84 prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
85     const
86 {
87     return nativeThrottled_;
88 }
89
90 prefix_ void senf::ppi::connector::PassiveConnector::throttle()
91 {
92     if (!throttled())
93         emitThrottle();
94     nativeThrottled_ = true;
95 }
96
97 prefix_ void senf::ppi::connector::PassiveConnector::unthrottle()
98 {
99     if (throttled() && ! remoteThrottled_) {
100         nativeThrottled_ = false;
101         emitUnthrottle();
102     } else
103         nativeThrottled_ = false;
104
105 }
106
107 prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
108     const
109 {
110     return dynamic_cast<ActiveConnector&>(Connector::peer());
111 }
112
113 ////////////////////////////////////////
114 // protected members
115
116 prefix_ senf::ppi::connector::PassiveConnector::PassiveConnector()
117     : callback_(), remoteThrottled_(), nativeThrottled_()
118 {}
119
120 prefix_ void senf::ppi::connector::PassiveConnector::emit()
121 {
122     BOOST_ASSERT(callback_);
123     if (!throttled())
124         callback_();
125 }
126
127 ////////////////////////////////////////
128 // private members
129
130 prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
131 {
132     if (!throttled()) {
133         remoteThrottled_ = true;
134         emitThrottle();
135     } 
136     else 
137         remoteThrottled_ = true;
138 }
139
140 prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
141 {
142     peer().notifyThrottle();
143 }
144
145 prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
146 {
147     peer().notifyUnthrottle();
148     v_unthrottleEvent();
149 }
150
151 prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
152 {}
153
154 prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
155 {
156     routes_.push_back(&route);
157 }
158
159 ///////////////////////////////////////////////////////////////////////////
160 // senf::ppi::connector::ActiveConnector
161
162 prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer()
163     const
164 {
165     return dynamic_cast<PassiveConnector&>(Connector::peer());
166 }
167
168 prefix_ void senf::ppi::connector::ActiveConnector::onThrottle()
169 {
170     throttleCallback_ = Callback();
171 }
172
173 prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle()
174 {
175     unthrottleCallback_ = Callback();
176 }
177
178 prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
179     const
180 {
181     return peer().throttled();
182 }
183
184 ////////////////////////////////////////
185 // protected members
186
187 prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector()
188     : throttleCallback_(), unthrottleCallback_(), notifyRoutes_()
189 {}
190
191 ///////////////////////////////////////////////////////////////////////////
192 // senf::ppi::connector::InputConnector
193
194 prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer()
195     const
196 {
197     return dynamic_cast<OutputConnector &>(Connector::peer());
198 }
199
200 prefix_ senf::ppi::connector::InputConnector::queue_iterator
201 senf::ppi::connector::InputConnector::begin()
202     const
203 {
204     return queue_.begin();
205 }
206
207 prefix_ senf::ppi::connector::InputConnector::queue_iterator
208 senf::ppi::connector::InputConnector::end()
209     const
210 {
211     return queue_.end();
212 }
213
214 prefix_ senf::Packet senf::ppi::connector::InputConnector::peek()
215     const
216 {
217     BOOST_ASSERT( ! queue_.empty() );
218     return queue_.back();
219 }
220
221 prefix_ senf::ppi::connector::InputConnector::size_type
222 senf::ppi::connector::InputConnector::queueSize()
223     const
224 {
225     return queue_.size();
226 }
227
228 prefix_ bool senf::ppi::connector::InputConnector::empty()
229     const
230 {
231     return queue_.empty();
232 }
233
234 ////////////////////////////////////////
235 // protected members
236
237 prefix_ senf::ppi::connector::InputConnector::InputConnector()
238 {}
239
240 ////////////////////////////////////////
241 // private members
242
243 prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet p)
244 {
245     queue_.push_front(p);
246     v_enqueueEvent();
247 }
248
249 ///////////////////////////////////////////////////////////////////////////
250 // senf::ppi::connector::OutputConnector
251
252 prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet p)
253 {
254     peer().enqueue(p);
255 }
256
257 prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
258     const
259 {
260     return dynamic_cast<InputConnector&>(Connector::peer());
261 }
262
263 ////////////////////////////////////////
264 // protected members
265
266 prefix_ senf::ppi::connector::OutputConnector::OutputConnector()
267 {}
268
269 ///////////////////////////////////////////////////////////////////////////
270 // senf::ppi::connector::PassiveInput
271
272 prefix_ senf::ppi::connector::PassiveInput::PassiveInput()
273     : qdisc_(new ThresholdQueueing(1,0))
274 {}
275
276 prefix_ senf::ppi::connector::ActiveOutput & senf::ppi::connector::PassiveInput::peer()
277     const
278 {
279     return dynamic_cast<ActiveOutput&>(Connector::peer());
280 }
281
282 prefix_ bool senf::ppi::connector::PassiveInput::boolean_test()
283     const
284 {
285     return ! empty();
286 }
287
288 ///////////////////////////////////////////////////////////////////////////
289 // senf::ppi::connector::PassiveOutput
290
291 prefix_ senf::ppi::connector::ActiveInput & senf::ppi::connector::PassiveOutput::peer()
292     const
293 {
294     return dynamic_cast<ActiveInput&>(Connector::peer());
295 }
296
297 prefix_ bool senf::ppi::connector::PassiveOutput::boolean_test()
298     const
299 {
300     return  true;
301 }
302
303 prefix_ void senf::ppi::connector::PassiveOutput::connect(ActiveInput & target)
304 {
305     Connector::connect(target);
306 }
307
308 ///////////////////////////////////////////////////////////////////////////
309 // senf::ppi::connector::ActiveInput
310
311 prefix_ senf::ppi::connector::PassiveOutput & senf::ppi::connector::ActiveInput::peer()
312     const
313 {
314     return dynamic_cast<PassiveOutput&>(Connector::peer());
315 }
316
317 prefix_ bool senf::ppi::connector::ActiveInput::boolean_test()
318     const
319 {
320     return ! empty() || ! peer().throttled();
321 }
322
323 prefix_ void senf::ppi::connector::ActiveInput::request()
324 {
325     peer().emit();
326 }
327
328 ///////////////////////////////////////////////////////////////////////////
329 // senf::ppi::connector::ActiveOutput
330
331 prefix_ senf::ppi::connector::PassiveInput & senf::ppi::connector::ActiveOutput::peer()
332     const
333 {
334     return dynamic_cast<PassiveInput&>(Connector::peer());
335 }
336
337 prefix_ bool senf::ppi::connector::ActiveOutput::boolean_test()
338     const
339 {
340     return ! peer().throttled();
341 }
342
343 prefix_ void senf::ppi::connector::ActiveOutput::connect(PassiveInput & target)
344 {
345     Connector::connect(target);
346 }
347
348 ///////////////////////////////cci.e///////////////////////////////////////
349 #undef prefix_
350
351 \f
352 // Local Variables:
353 // mode: c++
354 // fill-column: 100
355 // comment-column: 40
356 // c-file-style: "senf"
357 // indent-tabs-mode: nil
358 // ispell-local-dictionary: "american"
359 // compile-command: "scons -u test"
360 // End: