Update SENF to compile using g++ 4.3.2 (Ubuntu 8.10)
[senf.git] / PPI / Connectors.cc
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 non-inline non-template implementation */
25
26 #include "Connectors.hh"
27 #include "Connectors.ih"
28
29 // Custom includes
30 #include "Route.hh"
31 #include "Module.hh"
32 #include "ModuleManager.hh"
33
34 //#include "Connectors.mpp"
35 #define prefix_
36 ///////////////////////////////cc.p////////////////////////////////////////
37
38 ///////////////////////////////////////////////////////////////////////////
39 // senf::ppi::connector::Connector
40
41 prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
42 {
43     SENF_ASSERT( module_ && ! peer_ && target.module_ && ! target.peer_ );
44     if (! (packetTypeID() == typeid(void) ||
45            target.packetTypeID() == typeid(void) || 
46            packetTypeID() == target.packetTypeID()) )
47         throw IncompatibleConnectorsException() 
48             << ": " << prettyName(packetTypeID()) 
49             << " [in module " << prettyName(typeid(*module_))  << "] "
50             << ", " << prettyName(target.packetTypeID())
51             << " [in module " << prettyName(typeid(*target.module_)) << "]";
52             
53     peer_ = & target;
54     target.peer_ = this;
55
56     if (! initializationScheduled())
57         enqueueInitializable();
58     if (! peer().initializationScheduled())
59         peer().enqueueInitializable();
60 }
61
62 prefix_ void senf::ppi::connector::Connector::disconnect()
63 {
64     SENF_ASSERT( peer_ );
65     Connector & peer (*peer_);
66     peer_ = 0;
67     peer.peer_ = 0;
68
69     if (! initializationScheduled())
70         enqueueInitializable();
71     if (! peer.initializationScheduled())
72         peer.enqueueInitializable();
73 }
74
75 prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID()
76 {
77     return typeid(void);
78 }
79
80 ///////////////////////////////////////////////////////////////////////////
81 // senf::ppi::connector::PassiveConnector
82
83 ////////////////////////////////////////
84 // private members
85
86 prefix_ void senf::ppi::connector::PassiveConnector::v_init()
87 {
88     Routes::const_iterator i (routes_.begin());
89     Routes::const_iterator const i_end (routes_.end());
90     for (; i != i_end; ++i)
91         if ((*i)->throttled())
92             break;
93     if (i == i_end)
94         remoteThrottled_ = false;
95     if (throttled())
96         emitThrottle();
97     else
98         emitUnthrottle();
99 }
100
101 prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
102 {}
103
104 prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
105 {
106     if (throttled() && !nativeThrottled_) {
107         Routes::const_iterator i (routes_.begin());
108         Routes::const_iterator const i_end (routes_.end());
109         for (; i != i_end; ++i)
110             if ((*i)->throttled())
111                 break;
112         if (i == i_end) {
113             remoteThrottled_ = false;
114             emitUnthrottle();
115         }
116     } 
117     else
118         remoteThrottled_ = false;
119 }
120
121 ///////////////////////////////////////////////////////////////////////////
122 // senf::ppi::connector::ActiveConnector
123
124 ////////////////////////////////////////
125 // private members
126
127 prefix_ void senf::ppi::connector::ActiveConnector::v_init()
128 {
129     if (! connected())
130         notifyThrottle();
131 }
132
133 prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle()
134 {
135     if (! throttled_) {
136         throttled_ = true;
137         if (throttleCallback_)
138             throttleCallback_();
139         NotifyRoutes::const_iterator i (notifyRoutes_.begin());
140         NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
141         for (; i != i_end; ++i)
142             (*i)->notifyThrottle();
143     }
144 }
145
146 prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle()
147 {
148     if (throttled_) {
149         throttled_ = false;
150         if (unthrottleCallback_)
151             unthrottleCallback_();
152         NotifyRoutes::const_iterator i (notifyRoutes_.begin());
153         NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
154         for (; i != i_end; ++i)
155             (*i)->notifyUnthrottle();
156     }
157 }
158
159 prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRoute & route)
160 {
161     notifyRoutes_.push_back(&route);
162 }
163
164 ///////////////////////////////////////////////////////////////////////////
165 // senf::ppi::connector::InputConnector
166
167 prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()()
168 {
169     if (empty())
170         v_requestEvent();
171     Packet p;
172     if (! empty()) {
173         p = peek();
174         queue_.pop_back();
175         v_dequeueEvent();
176     }
177     return p;
178 }
179
180 ////////////////////////////////////////
181 // private members
182
183 prefix_ void senf::ppi::connector::InputConnector::v_requestEvent()
184 {}
185
186 prefix_ void senf::ppi::connector::InputConnector::v_enqueueEvent()
187 {}
188
189 prefix_ void senf::ppi::connector::InputConnector::v_dequeueEvent()
190 {}
191
192 ///////////////////////////////////////////////////////////////////////////
193 // senf::ppi::connector::GenericActiveInput
194
195 ////////////////////////////////////////
196 // private members
197
198 prefix_ void senf::ppi::connector::GenericActiveInput::v_requestEvent()
199 {
200     request();
201 }
202
203 ///////////////////////////////////////////////////////////////////////////
204 // senf::ppi::connector::GenericPassiveInput
205
206 ////////////////////////////////////////
207 // private members 
208
209 prefix_ void senf::ppi::connector::GenericPassiveInput::v_enqueueEvent()
210 {
211     emit();
212     qdisc_->update(*this, QueueingDiscipline::ENQUEUE);
213 }
214
215 prefix_ void senf::ppi::connector::GenericPassiveInput::v_dequeueEvent()
216 {
217     qdisc_->update(*this, QueueingDiscipline::DEQUEUE);
218 }
219
220 prefix_ void senf::ppi::connector::GenericPassiveInput::v_unthrottleEvent()
221 {
222     size_type n (queueSize());
223     while (n) {
224         emit();
225         size_type nn (queueSize());
226         if (n == nn)
227             break;
228         n = nn;
229     }
230 }
231
232 ///////////////////////////////cc.e////////////////////////////////////////
233 #undef prefix_
234 //#include "Connectors.mpp"
235
236 \f
237 // Local Variables:
238 // mode: c++
239 // fill-column: 100
240 // comment-column: 40
241 // c-file-style: "senf"
242 // indent-tabs-mode: nil
243 // ispell-local-dictionary: "american"
244 // compile-command: "scons -u test"
245 // End: