Socket: Add missing InetSocketProtocol baseclass to relevant socket protocols
[senf.git] / PPI / Connectors.cc
index 224eab2..ab1a038 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
-// Copyright (C) 2007 
-// Fraunhofer Institute for Open Communication Systems (FOKUS) 
-// Competence Center NETwork research (NET), St. Augustin, GERMANY 
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
     \brief Connectors non-inline non-template implementation */
 
 #include "Connectors.hh"
-//#include "Connectors.ih"
+#include "Connectors.ih"
 
 // Custom includes
 #include "Route.hh"
+#include "Module.hh"
+#include "ModuleManager.hh"
 
 //#include "Connectors.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
+// senf::ppi::connector::Connector
+
+prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
+{
+    SENF_ASSERT( module_ && ! peer_ && target.module_ && ! target.peer_ );
+    if (! (packetTypeID() == typeid(void) ||
+           target.packetTypeID() == typeid(void) || 
+           packetTypeID() == target.packetTypeID()) )
+        throw IncompatibleConnectorsException() 
+            << ": " << prettyName(packetTypeID()) 
+            << " [in module " << prettyName(typeid(*module_))  << "] "
+            << ", " << prettyName(target.packetTypeID())
+            << " [in module " << prettyName(typeid(*target.module_)) << "]";
+            
+    peer_ = & target;
+    target.peer_ = this;
+
+    if (ModuleManager::instance().running())
+        v_init();
+}
+
+prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID()
+{
+    return typeid(void);
+}
+
+///////////////////////////////////////////////////////////////////////////
 // senf::ppi::connector::PassiveConnector
 
 ////////////////////////////////////////
 // private members
 
+prefix_ void senf::ppi::connector::PassiveConnector::v_init()
+{
+    Routes::const_iterator i (routes_.begin());
+    Routes::const_iterator const i_end (routes_.end());
+    for (; i != i_end; ++i)
+        if ((*i)->throttled())
+            break;
+    if (i == i_end)
+        remoteThrottled_ = false;
+    if (throttled())
+        emitThrottle();
+    else
+        emitUnthrottle();
+}
+
+prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
+{}
+
 prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
 {
     if (throttled() && !nativeThrottled_) {
@@ -62,24 +109,36 @@ prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
 ////////////////////////////////////////
 // private members
 
+prefix_ void senf::ppi::connector::ActiveConnector::v_init()
+{
+    if (! connected())
+        notifyThrottle();
+}
+
 prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle()
 {
-    if (throttleCallback_)
-        throttleCallback_();
-    NotifyRoutes::const_iterator i (notifyRoutes_.begin());
-    NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
-    for (; i != i_end; ++i)
-        (*i)->notifyThrottle();
+    if (! throttled_) {
+        throttled_ = true;
+        if (throttleCallback_)
+            throttleCallback_();
+        NotifyRoutes::const_iterator i (notifyRoutes_.begin());
+        NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
+        for (; i != i_end; ++i)
+            (*i)->notifyThrottle();
+    }
 }
 
 prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle()
 {
-    if (unthrottleCallback_)
-        unthrottleCallback_();
-    NotifyRoutes::const_iterator i (notifyRoutes_.begin());
-    NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
-    for (; i != i_end; ++i)
-        (*i)->notifyUnthrottle();
+    if (throttled_) {
+        throttled_ = false;
+        if (unthrottleCallback_)
+            unthrottleCallback_();
+        NotifyRoutes::const_iterator i (notifyRoutes_.begin());
+        NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
+        for (; i != i_end; ++i)
+            (*i)->notifyUnthrottle();
+    }
 }
 
 prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRoute & route)
@@ -116,34 +175,34 @@ prefix_ void senf::ppi::connector::InputConnector::v_dequeueEvent()
 {}
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::ActiveInput
+// senf::ppi::connector::GenericActiveInput
 
 ////////////////////////////////////////
 // private members
 
-prefix_ void senf::ppi::connector::ActiveInput::v_requestEvent()
+prefix_ void senf::ppi::connector::GenericActiveInput::v_requestEvent()
 {
     request();
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::PassiveInput
+// senf::ppi::connector::GenericPassiveInput
 
 ////////////////////////////////////////
 // private members 
 
-prefix_ void senf::ppi::connector::PassiveInput::v_enqueueEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_enqueueEvent()
 {
     emit();
     qdisc_->update(*this, QueueingDiscipline::ENQUEUE);
 }
 
-prefix_ void senf::ppi::connector::PassiveInput::v_dequeueEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_dequeueEvent()
 {
     qdisc_->update(*this, QueueingDiscipline::DEQUEUE);
 }
 
-prefix_ void senf::ppi::connector::PassiveInput::v_unthrottleEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_unthrottleEvent()
 {
     size_type n (queueSize());
     while (n) {