// $Id$ // // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file \brief Connectors inline non-template implementation */ // Custom includes #include #include #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::Connector prefix_ senf::ppi::connector::Connector & senf::ppi::connector::Connector::peer() const { // The connector is not connected SENF_ASSERT(peer_ && "senf::ppi::connect() call missing"); return *peer_; } prefix_ senf::ppi::module::Module & senf::ppi::connector::Connector::module() const { // The connector is not registered in the module -> probably a route() or noroute() statement is // missing. SENF_ASSERT(module_ && "Connector not registered: Missing route() or noroute()"); return *module_; } prefix_ void senf::ppi::connector::Connector::tracing(TraceState state) { traceState_ = state; } prefix_ senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::tracing() { return traceState_; } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::Connector::Connector() : peer_(), module_() {} prefix_ senf::ppi::connector::Connector::~Connector() { if (connected()) { Connector & peer (*peer_); peer_->peer_ = 0; peer.v_init(); } } prefix_ bool senf::ppi::connector::Connector::connected() const { return peer_; } //////////////////////////////////////// // private members prefix_ void senf::ppi::connector::Connector::setModule(module::Module & module) { module_ = &module; } /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::PassiveConnector prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer() const { return dynamic_cast(Connector::peer()); } prefix_ bool senf::ppi::connector::PassiveConnector::throttled() const { return nativeThrottled_ || remoteThrottled_; } //////////////////////////////////////// // private members prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle() { throttleTrace("OUT", "throttle"); if (connected()) peer().notifyThrottle(); } prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle() { throttleTrace("OUT", "unthrottle"); if (connected()) { peer().notifyUnthrottle(); v_unthrottleEvent(); } } prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle() { if (!throttled()) { remoteThrottled_ = true; emitThrottle(); } else remoteThrottled_ = true; } prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route) { routes_.push_back(&route); } // public members prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled() const { return nativeThrottled_; } prefix_ void senf::ppi::connector::PassiveConnector::throttle() { if (!throttled()) { nativeThrottled_ = true; emitThrottle(); } else nativeThrottled_ = true; } prefix_ void senf::ppi::connector::PassiveConnector::unthrottle() { if (throttled() && ! remoteThrottled_) { nativeThrottled_ = false; emitUnthrottle(); } else nativeThrottled_ = false; } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::PassiveConnector::PassiveConnector() : callback_(), remoteThrottled_(), nativeThrottled_() {} prefix_ void senf::ppi::connector::PassiveConnector::emit() { // No event callback has been registered (onRequest() call missing) SENF_ASSERT(callback_ && "senf::ppi::connector::PassiveConnector: missing onRequest()"); if (!throttled()) callback_(); else throttleTrace("IN ", "queueing packet"); } /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::ActiveConnector prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer() const { return dynamic_cast(Connector::peer()); } prefix_ void senf::ppi::connector::ActiveConnector::onThrottle() { throttleCallback_ = Callback(); } prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle() { unthrottleCallback_ = Callback(); } prefix_ bool senf::ppi::connector::ActiveConnector::throttled() const { return ! connected() || peer().throttled(); } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector() : throttleCallback_(), unthrottleCallback_(), notifyRoutes_(), throttled_(false) {} /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::InputConnector prefix_ senf::Packet senf::ppi::connector::InputConnector::read() { return operator()(); } prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer() const { return dynamic_cast(Connector::peer()); } prefix_ senf::ppi::connector::InputConnector::queue_iterator senf::ppi::connector::InputConnector::begin() const { return queue_.begin(); } prefix_ senf::ppi::connector::InputConnector::queue_iterator senf::ppi::connector::InputConnector::end() const { return queue_.end(); } prefix_ senf::Packet senf::ppi::connector::InputConnector::peek() const { // Cannot peek() head of empty queue SENF_ASSERT( ! queue_.empty() && "senf::ppi::connector::InputConnector: cannot call peek() on empty queue" ); return queue_.back(); } prefix_ senf::ppi::connector::InputConnector::size_type senf::ppi::connector::InputConnector::queueSize() const { return queue_.size(); } prefix_ bool senf::ppi::connector::InputConnector::empty() const { return queue_.empty(); } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::InputConnector::InputConnector() {} //////////////////////////////////////// // private members prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet const & p) { queue_.push_front(p); v_enqueueEvent(); } /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::OutputConnector prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer() const { return dynamic_cast(Connector::peer()); } prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p) { trace(p, "OUT"); if (connected()) peer().enqueue(p); } prefix_ void senf::ppi::connector::OutputConnector::write(Packet const & p) { operator()(p); } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::OutputConnector::OutputConnector() {} /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::GenericPassiveInput prefix_ senf::ppi::connector::GenericPassiveInput::GenericPassiveInput() : qdisc_(new ThresholdQueueing(1,0)) {} prefix_ senf::ppi::connector::GenericActiveOutput & senf::ppi::connector::GenericPassiveInput::peer() const { return dynamic_cast(Connector::peer()); } prefix_ bool senf::ppi::connector::GenericPassiveInput::boolean_test() const { return ! empty(); } /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::GenericPassiveOutput prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connector::GenericPassiveOutput::peer() const { return dynamic_cast(Connector::peer()); } prefix_ bool senf::ppi::connector::GenericPassiveOutput::boolean_test() const { return true; } prefix_ void senf::ppi::connector::GenericPassiveOutput::connect(GenericActiveInput & target) { Connector::connect(target); } prefix_ senf::ppi::connector::GenericPassiveOutput::GenericPassiveOutput() {} /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::GenericActiveInput prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::GenericActiveInput::peer() const { return dynamic_cast(Connector::peer()); } prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test() const { return ! empty() || (connected() && ! peer().throttled()); } prefix_ void senf::ppi::connector::GenericActiveInput::request() { if (connected()) peer().emit(); } prefix_ senf::ppi::connector::GenericActiveInput::GenericActiveInput() {} /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::GenericActiveOutput prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::GenericActiveOutput::peer() const { return dynamic_cast(Connector::peer()); } prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test() const { return connected() && ! peer().throttled(); } prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target) { Connector::connect(target); } prefix_ senf::ppi::connector::GenericActiveOutput::GenericActiveOutput() {} ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ // Local Variables: // mode: c++ // fill-column: 100 // comment-column: 40 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // End: