// $Id$ // // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // All Rights Reserved. // // Contributor(s): // Stefan Bund /** \file \brief Connectors inline non-template implementation */ // Custom includes #include #include #include "Module.hh" #define prefix_ inline //-///////////////////////////////////////////////////////////////////////////////////////////////// #ifdef SENF_PPI_NOTRACE # define SENF_PPI_THROTTLE_TRACE(label, type) # define SENF_PPI_TRACE(packet, label) #else # define SENF_PPI_THROTTLE_TRACE(label, type) throttleTrace(label, type) # define SENF_PPI_TRACE(packet, label) trace(packet, label) #endif //-///////////////////////////////////////////////////////////////////////////////////////////////// // 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_ bool senf::ppi::connector::Connector::connected() const { return peer_; } //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::PassiveConnector prefix_ senf::ppi::connector::ActiveConnector & senf::ppi::connector::PassiveConnector::peer() const { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *peer_; } prefix_ bool senf::ppi::connector::PassiveConnector::throttled() const { return nativeThrottled_ || remoteThrottled_; } //-///////////////////////////////////////////////////////////////////////////////////////////////// // private members prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle() { SENF_PPI_THROTTLE_TRACE("OUT", "throttle"); if (connected()) peer().notifyThrottle(); } prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle() { SENF_PPI_THROTTLE_TRACE("OUT", "unthrottle"); if (connected()) { peer().notifyUnthrottle(); v_unthrottleEvent(); } } prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle() { if (!throttled()) { remoteThrottled_ = true; emitThrottle(); } else remoteThrottled_ = true; } // 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 { SENF_PPI_THROTTLE_TRACE("IN ", "queueing packet"); } } //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::ActiveConnector prefix_ senf::ppi::connector::PassiveConnector & senf::ppi::connector::ActiveConnector::peer() const { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *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 const & senf::ppi::connector::InputConnector::read() { return operator()(); } prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConnector::peer() const { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *peer_; } prefix_ senf::ppi::connector::InputConnector::size_type senf::ppi::connector::InputConnector::queueSize() const { return queue_.size() + (fastPacket_ ? 1 : 0); } prefix_ bool senf::ppi::connector::InputConnector::empty() const { return fastPacket_ == NULL && queue_.empty(); } //-///////////////////////////////////////////////////////////////////////////////////////////////// // protected members prefix_ senf::ppi::connector::InputConnector::InputConnector() : fastPacket_(NULL) {} //-///////////////////////////////////////////////////////////////////////////////////////////////// // private members prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet const & p) { if (queue_.empty()) { fastPacket_ = &p; try { v_enqueueEvent(); } catch (Exception & e) { queue_.push_front(p); throw e; } if (fastPacket_) { queue_.push_front(p); fastPacket_ = NULL; } } else { queue_.push_front(p); v_enqueueEvent(); } } //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::OutputConnector prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConnector::peer() const { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *peer_; } prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p) { SENF_PPI_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 { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *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 { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *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 { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *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 { SENF_ASSERT(peer_, "senf::ppi::connect() call missing"); return *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() {} //-///////////////////////////////////////////////////////////////////////////////////////////////// #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: