2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
15 \brief Connectors inline non-template implementation */
18 #include <senf/Utils/TypeInfo.hh>
19 #include <senf/Utils/senfassert.hh>
20 #include <senf/Utils/senflikely.hh>
22 #define prefix_ inline
23 //-/////////////////////////////////////////////////////////////////////////////////////////////////
25 #ifdef SENF_PPI_NOTRACE
26 # define SENF_PPI_THROTTLE_TRACE(label, type)
27 # define SENF_PPI_TRACE(packet, label)
29 # define SENF_PPI_THROTTLE_TRACE(label, type) throttleTrace(label, type)
30 # define SENF_PPI_TRACE(packet, label) trace(packet, label)
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34 // senf::ppi::connector::Connector
36 prefix_ senf::ppi::connector::Connector & senf::ppi::connector::Connector::peer()
39 // The connector is not connected
40 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
44 #ifndef SENF_PPI_NOTRACE
45 prefix_ void senf::ppi::connector::Connector::staticTracingState(TraceState state)
47 staticTraceState_ = state;
50 prefix_ senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::tracingState()
53 return std::max(staticTraceState_, traceState_);
56 prefix_ void senf::ppi::connector::Connector::tracingState(TraceState state)
61 prefix_ void senf::ppi::connector::Connector::tracingFilter(std::string const & traceFilter)
63 traceFilter_ = traceFilter;
67 //-/////////////////////////////////////////////////////////////////////////////////////////////////
70 prefix_ bool senf::ppi::connector::Connector::connected()
76 prefix_ senf::console::DirectoryNode & senf::ppi::connector::Connector::consoleDir()
79 return consoleDir_.node();
82 //-/////////////////////////////////////////////////////////////////////////////////////////////////
83 // senf::ppi::connector::PassiveConnector
85 prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer()
88 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
92 prefix_ bool senf::ppi::connector::PassiveConnector::throttled()
95 return nativeThrottled_ || remoteThrottled_;
98 //-/////////////////////////////////////////////////////////////////////////////////////////////////
101 prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
103 SENF_PPI_THROTTLE_TRACE("OUT", "throttle");
104 if (SENF_LIKELY(connected()))
105 peer().notifyThrottle();
108 prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle()
110 SENF_PPI_THROTTLE_TRACE("OUT", "unthrottle");
111 if (SENF_LIKELY(connected())) {
112 peer().notifyUnthrottle();
117 prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle()
119 if (SENF_LIKELY(!throttled())) {
120 remoteThrottled_ = true;
124 remoteThrottled_ = true;
129 prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
132 return nativeThrottled_;
135 prefix_ void senf::ppi::connector::PassiveConnector::throttle()
137 if (SENF_LIKELY(!throttled())) {
138 nativeThrottled_ = true;
141 nativeThrottled_ = true;
144 prefix_ void senf::ppi::connector::PassiveConnector::unthrottle()
146 if (throttled() && ! remoteThrottled_) {
147 nativeThrottled_ = false;
150 nativeThrottled_ = false;
154 //-/////////////////////////////////////////////////////////////////////////////////////////////////
157 prefix_ void senf::ppi::connector::PassiveConnector::emit()
159 // No event callback has been registered (onRequest() call missing)
160 SENF_ASSERT(callback_, "senf::ppi::connector::PassiveConnector: missing onRequest()");
161 if (SENF_LIKELY(!throttled())) {
164 SENF_PPI_THROTTLE_TRACE("IN ", "queueing packet");
168 //-/////////////////////////////////////////////////////////////////////////////////////////////////
169 // senf::ppi::connector::ActiveConnector
171 prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer()
174 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
178 prefix_ void senf::ppi::connector::ActiveConnector::onThrottle()
180 throttleCallback_ = Callback();
183 prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle()
185 unthrottleCallback_ = Callback();
188 prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
191 return ! connected() || peer().throttled();
194 //-/////////////////////////////////////////////////////////////////////////////////////////////////
197 prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector()
198 : peer_(nullptr), throttled_(false)
201 //-/////////////////////////////////////////////////////////////////////////////////////////////////
202 // senf::ppi::connector::InputConnector
204 prefix_ senf::Packet const & senf::ppi::connector::InputConnector::read()
209 prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer()
212 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
216 prefix_ senf::ppi::connector::InputConnector::size_type
217 senf::ppi::connector::InputConnector::queueSize()
220 // return queue_.size() + (fastPacket_ ? 1 : 0);
221 return queue_.size() + bool(fastPacket_);
224 prefix_ bool senf::ppi::connector::InputConnector::empty()
227 return fastPacket_ == nullptr && queue_.empty();
230 //-/////////////////////////////////////////////////////////////////////////////////////////////////
233 prefix_ senf::ppi::connector::InputConnector::InputConnector()
234 : peer_(nullptr), fastPacket_(nullptr)
237 //-/////////////////////////////////////////////////////////////////////////////////////////////////
240 prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet const & p)
242 if (SENF_LIKELY(queue_.empty())) {
246 } catch (Exception & e) {
248 queue_.push_front(p);
249 fastPacket_ = nullptr;
253 if (SENF_UNLIKELY(fastPacket_)) {
254 queue_.push_front(p);
255 fastPacket_ = nullptr;
258 queue_.push_front(p);
264 //-/////////////////////////////////////////////////////////////////////////////////////////////////
265 // senf::ppi::connector::OutputConnector
267 prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer()
270 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
274 prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p)
276 SENF_PPI_TRACE(p, "OUT");
277 if (SENF_LIKELY(connected()))
281 prefix_ void senf::ppi::connector::OutputConnector::write(Packet const & p)
286 //-/////////////////////////////////////////////////////////////////////////////////////////////////
289 prefix_ senf::ppi::connector::OutputConnector::OutputConnector()
293 //-/////////////////////////////////////////////////////////////////////////////////////////////////
294 // senf::ppi::connector::GenericPassiveInput
296 prefix_ senf::ppi::connector::GenericPassiveInput::GenericPassiveInput()
297 : peer_(nullptr), throttlingDisc_(new ThresholdThrottling(1,0))
300 prefix_ senf::ppi::connector::GenericActiveOutput & senf::ppi::connector::GenericPassiveInput::peer()
303 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
307 prefix_ bool senf::ppi::connector::GenericPassiveInput::boolean_test()
313 //-/////////////////////////////////////////////////////////////////////////////////////////////////
314 // senf::ppi::connector::GenericPassiveOutput
316 prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connector::GenericPassiveOutput::peer()
319 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
323 prefix_ bool senf::ppi::connector::GenericPassiveOutput::boolean_test()
329 prefix_ void senf::ppi::connector::GenericPassiveOutput::connect(GenericActiveInput & target)
331 OutputConnector::connect(target);
334 prefix_ senf::ppi::connector::GenericPassiveOutput::GenericPassiveOutput()
338 //-/////////////////////////////////////////////////////////////////////////////////////////////////
339 // senf::ppi::connector::GenericActiveInput
341 prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::GenericActiveInput::peer()
344 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
348 prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test()
351 return ! empty() || (connected() && ! peer().throttled());
354 prefix_ void senf::ppi::connector::GenericActiveInput::request()
356 if (SENF_LIKELY(connected()))
360 prefix_ senf::ppi::connector::GenericActiveInput::GenericActiveInput()
364 //-/////////////////////////////////////////////////////////////////////////////////////////////////
365 // senf::ppi::connector::GenericActiveOutput
367 prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::GenericActiveOutput::peer()
370 SENF_ASSERT(peer_, "senf::ppi::connect() call missing");
374 prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test()
377 return connected() && ! peer().throttled();
380 prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target)
382 OutputConnector::connect(target);
385 prefix_ senf::ppi::connector::GenericActiveOutput::GenericActiveOutput()
389 //-/////////////////////////////////////////////////////////////////////////////////////////////////
396 // comment-column: 40
397 // c-file-style: "senf"
398 // indent-tabs-mode: nil
399 // ispell-local-dictionary: "american"
400 // compile-command: "scons -u test"