4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief Connectors non-inline non-template implementation */
26 #include "Connectors.hh"
27 #include "Connectors.ih"
32 #include "ModuleManager.hh"
33 #include "../Utils/Console/Console.hh"
35 //#include "Connectors.mpp"
37 ///////////////////////////////cc.p////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////
40 // senf::ppi::connector::Connector
42 prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
44 // The connector is not registered -> route() or noroute() statement missing
45 SENF_ASSERT( module_ &&
46 "senf::ppi::connector::Connector::connect(): (source) "
47 "Missing route() or noroute()" );
48 // The connector is already connected
49 SENF_ASSERT( ! peer_ &&
50 "senf::ppi::connector::Connector::connect(): (source) "
51 "duplicate connection" );
52 // The target connector is not registered -> route() or noroute() statement missing
53 SENF_ASSERT( target.module_ &&
54 "senf::ppi::connector::Connector::connect(): (target) "
55 "Missing route() or noroute()" );
56 // The target connector is already connected
57 SENF_ASSERT( ! target.peer_ &&
58 "senf::ppi::connector::Connector::connect(): (target) "
59 "duplicate connection" );
60 if (! (packetTypeID() == typeid(void) ||
61 target.packetTypeID() == typeid(void) ||
62 packetTypeID() == target.packetTypeID()) )
63 throw IncompatibleConnectorsException()
64 << ": " << prettyName(packetTypeID())
65 << " [in module " << prettyName(typeid(*module_)) << "] "
66 << ", " << prettyName(target.packetTypeID())
67 << " [in module " << prettyName(typeid(*target.module_)) << "]";
72 if (! initializationScheduled())
73 enqueueInitializable();
74 if (! peer().initializationScheduled())
75 peer().enqueueInitializable();
78 senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::traceState_ (
79 senf::ppi::connector::Connector::NO_TRACING);
81 prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const * label)
83 if (traceState_ == NO_TRACING)
86 std::string type (prettyName(p.typeId().id()));
87 log << "PPI trace: " << label << " 0x" << std::hex << p.id() << " "
88 << type.substr(21, type.size()-22) << " on " << & module() << " "
89 << prettyName(typeid(module())) << " connector 0x" << this << "\n";
90 if (traceState_ == TRACE_CONTENTS)
95 namespace senf { namespace ppi { namespace connector {
97 SENF_CONSOLE_REGISTER_ENUM_MEMBER(
98 Connector, TraceState, (NO_TRACING)(TRACE_IDS)(TRACE_CONTENTS) );
104 struct ConsoleRegister
109 ConsoleRegister::ConsoleRegister()
111 senf::ppi::ModuleManager::instance().consoleDir()
112 .add("tracing", SENF_FNP(senf::ppi::connector::Connector::TraceState,
113 senf::ppi::connector::Connector::tracing, ()))
114 .doc("Log every packet sent or received by any module.\n"
115 "There are three different tracing levels:\n"
117 " NO_TRACING don't output any tracing information\n"
118 " TRACE_IDS trace packet id's but do not show packet contents\n"
119 " TRACE_CONTENTS trace complete packet contents\n"
121 "A log message is generated whenever the packet traverses a connector. The\n"
122 "TRACE_IDS log message has the following format:\n"
124 " PPI trace: <packet-id> <packet-type> <direction>\n"
125 " on <module-id> <module-type> connector <connector-id>\n"
129 " packet-id Numeric unique packet id. This value is unique for packets\n"
130 " alive at the same time, packets at different times may (and\n"
131 " will) share id's\n"
132 " packet-type The type of the packet header\n"
133 " direction 'INCOMING' for packets entering the module, 'OUTGOING' for\n"
134 " packets leaving it\n"
135 " module-id Unique module id\n"
136 " module-type Type of the module the packet is sent to/from\n"
137 " connector-id Unique connector id\n");
139 senf::ppi::ModuleManager::instance().consoleDir()
140 .add("tracing", SENF_FNP(void, senf::ppi::connector::Connector::tracing,
141 (senf::ppi::connector::Connector::TraceState)))
142 .arg("state", "new tracing state");
145 ConsoleRegister consoleRegister;
149 prefix_ void senf::ppi::connector::Connector::disconnect()
151 // Cannot disconnected a non-connected connector
152 SENF_ASSERT( peer_ &&
153 "senf::ppi::connector::Connector::disconnect(): Not connected" );
154 Connector & peer (*peer_);
158 if (! initializationScheduled())
159 enqueueInitializable();
160 if (! peer.initializationScheduled())
161 peer.enqueueInitializable();
164 prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID()
169 ///////////////////////////////////////////////////////////////////////////
170 // senf::ppi::connector::PassiveConnector
172 ////////////////////////////////////////
175 prefix_ void senf::ppi::connector::PassiveConnector::v_init()
177 Routes::const_iterator i (routes_.begin());
178 Routes::const_iterator const i_end (routes_.end());
179 for (; i != i_end; ++i)
180 if ((*i)->throttled())
183 remoteThrottled_ = false;
190 prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
193 prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
195 if (std::find_if(routes_.begin(), routes_.end(),
196 boost::bind(&ForwardingRoute::throttled, _1)) == routes_.end()) {
197 remoteThrottled_ = false;
198 if (!nativeThrottled_)
203 ///////////////////////////////////////////////////////////////////////////
204 // senf::ppi::connector::ActiveConnector
206 ////////////////////////////////////////
209 prefix_ void senf::ppi::connector::ActiveConnector::v_init()
215 prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle()
219 if (throttleCallback_)
221 NotifyRoutes::const_iterator i (notifyRoutes_.begin());
222 NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
223 for (; i != i_end; ++i)
224 (*i)->notifyThrottle();
228 prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle()
232 if (unthrottleCallback_)
233 unthrottleCallback_();
234 NotifyRoutes::const_iterator i (notifyRoutes_.begin());
235 NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
236 for (; i != i_end; ++i)
237 (*i)->notifyUnthrottle();
241 prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRoute & route)
243 notifyRoutes_.push_back(&route);
246 ///////////////////////////////////////////////////////////////////////////
247 // senf::ppi::connector::InputConnector
249 prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()()
259 trace(p, "INCOMING");
263 ////////////////////////////////////////
266 prefix_ void senf::ppi::connector::InputConnector::v_requestEvent()
269 prefix_ void senf::ppi::connector::InputConnector::v_enqueueEvent()
272 prefix_ void senf::ppi::connector::InputConnector::v_dequeueEvent()
275 ///////////////////////////////////////////////////////////////////////////
276 // senf::ppi::connector::GenericActiveInput
278 ////////////////////////////////////////
281 prefix_ void senf::ppi::connector::GenericActiveInput::v_requestEvent()
286 ///////////////////////////////////////////////////////////////////////////
287 // senf::ppi::connector::GenericPassiveInput
289 ////////////////////////////////////////
292 prefix_ void senf::ppi::connector::GenericPassiveInput::v_enqueueEvent()
295 qdisc_->update(*this, QueueingDiscipline::ENQUEUE);
298 prefix_ void senf::ppi::connector::GenericPassiveInput::v_dequeueEvent()
300 qdisc_->update(*this, QueueingDiscipline::DEQUEUE);
303 prefix_ void senf::ppi::connector::GenericPassiveInput::v_unthrottleEvent()
305 size_type n (queueSize());
308 size_type nn (queueSize());
315 ///////////////////////////////cc.e////////////////////////////////////////
317 //#include "Connectors.mpp"
323 // comment-column: 40
324 // c-file-style: "senf"
325 // indent-tabs-mode: nil
326 // ispell-local-dictionary: "american"
327 // compile-command: "scons -u test"