diff --git a/PPI/Connectors.cc b/PPI/Connectors.cc index cf241d5ec95047d15dc9010c5250ccb7f29a901f..ce44e0d23784c73237c77ee2ba399303fb61d9a6 100644 --- a/PPI/Connectors.cc +++ b/PPI/Connectors.cc @@ -84,7 +84,7 @@ prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const return; SENF_LOG_BLOCK(({ std::string type (prettyName(p.typeId().id())); - log << "PPI trace: " << label << " 0x" << std::hex << p.id() << " " + log << "PPI packet trace: " << label << " 0x" << std::hex << p.id() << " " << type.substr(21, type.size()-22) << " on " << & module() << " " << prettyName(typeid(module())) << " connector 0x" << this << "\n"; if (traceState_ == TRACE_CONTENTS) @@ -92,6 +92,17 @@ prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const })); } +prefix_ void senf::ppi::connector::Connector::throttleTrace(char const * label, + char const * type) +{ + if (traceState_ == NO_TRACING) + return; + SENF_LOG_BLOCK(({ + log << "PPI throttling trace: " << label << " " << type << " on " << & module() + << " " << prettyName(typeid(module())) << " connector 0x" << this << "\n"; + })); +} + namespace senf { namespace ppi { namespace connector { SENF_CONSOLE_REGISTER_ENUM_MEMBER( @@ -121,20 +132,23 @@ namespace { "A log message is generated whenever the packet traverses a connector. The\n" "TRACE_IDS log message has the following format:\n" "\n" - " PPI trace: <packet-id> <packet-type> <direction>\n" + " PPI packet trace: <direction> <packet-id> <packet-type>\n" + " on <module-id> <module-type> connector <connector-id>\n" + " PPI throttling trace: <direction> <throttle-msg>\n" " on <module-id> <module-type> connector <connector-id>\n" "\n" "The fields are:\n" "\n" + " direction 'IN' for packets/throttle notifications entering the module,\n" + " 'OUT' for packets/throttle notifications leaving it\n" " packet-id Numeric unique packet id. This value is unique for packets\n" " alive at the same time, packets at different times may (and\n" " will) share id's\n" " packet-type The type of the packet header\n" - " direction 'INCOMING' for packets entering the module, 'OUTGOING' for\n" - " packets leaving it\n" " module-id Unique module id\n" " module-type Type of the module the packet is sent to/from\n" - " connector-id Unique connector id\n"); + " connector-id Unique connector id\n" + " throttle-msg Type of throttling event\n"); senf::ppi::ModuleManager::instance().consoleDir() .add("tracing", SENF_FNP(void, senf::ppi::connector::Connector::tracing, @@ -197,7 +211,8 @@ prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle() remoteThrottled_ = false; if (!nativeThrottled_) emitUnthrottle(); - } + } else + throttleTrace("OUT", "not forwarding unthrottle event"); } /////////////////////////////////////////////////////////////////////////// @@ -214,6 +229,7 @@ prefix_ void senf::ppi::connector::ActiveConnector::v_init() prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle() { + throttleTrace("IN ", "throttle"); if (! throttled_) { throttled_ = true; if (throttleCallback_) @@ -227,6 +243,7 @@ prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle() prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle() { + throttleTrace("IN ", "unthrottle"); if (throttled_) { throttled_ = false; if (unthrottleCallback_) @@ -256,7 +273,7 @@ prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()() queue_.pop_back(); v_dequeueEvent(); } - trace(p, "INCOMING"); + trace(p, "IN "); return p; } diff --git a/PPI/Connectors.cci b/PPI/Connectors.cci index f480b02d32a40eb4b6b99c306d75c2ab29cfe202..ec587ceffa54580e0a2c862ea3c5498d8b5fadbc 100644 --- a/PPI/Connectors.cci +++ b/PPI/Connectors.cci @@ -110,12 +110,14 @@ prefix_ bool senf::ppi::connector::PassiveConnector::throttled() 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(); @@ -150,7 +152,8 @@ prefix_ void senf::ppi::connector::PassiveConnector::throttle() if (!throttled()) { nativeThrottled_ = true; emitThrottle(); - } + } else + nativeThrottled_ = true; } prefix_ void senf::ppi::connector::PassiveConnector::unthrottle() @@ -176,6 +179,8 @@ prefix_ void senf::ppi::connector::PassiveConnector::emit() SENF_ASSERT(callback_ && "senf::ppi::connector::PassiveConnector: missing onRequest()"); if (!throttled()) callback_(); + else + throttleTrace("IN ", "queueing packet"); } /////////////////////////////////////////////////////////////////////////// @@ -286,7 +291,7 @@ prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConne prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p) { - trace(p, "OUTGOING"); + trace(p, "OUT"); if (connected()) peer().enqueue(p); } diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index 002154ee48f81172cc463705c3363dea521dc15f..e6b8c07af00c67d44e45ce232f4841876907d891 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -183,6 +183,7 @@ namespace connector { void connect(Connector & target); void trace(Packet const & p, char const * label); + void throttleTrace(char const * label, char const * type); private: virtual std::type_info const & packetTypeID(); @@ -247,11 +248,11 @@ namespace connector { private: virtual void v_init(); - // Called by the routing to change the remote throttling state + // Called by the routing to change the throttling state from forwarding routes void notifyThrottle(); ///< Forward a throttle notification to this connector void notifyUnthrottle(); ///< Forward an unthrottle notification to this connector - // Internal members to emit throttling notifications + // Internal members to emit throttling notifications to the connected peer void emitThrottle(); void emitUnthrottle(); diff --git a/PPI/Events.cc b/PPI/Events.cc index 3525d3db9bfdf79424db17d40c7e5da631db6284..7aa02989e50ed191fcd3a4f02da811d99c86d058 100644 --- a/PPI/Events.cc +++ b/PPI/Events.cc @@ -43,13 +43,17 @@ prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle() for (; i != i_end; ++i) if ((*i)->throttled()) break; - if (i == i_end) - enabled(true); + if (i != i_end) + return; + throttled_ = false; + enabled(true); } prefix_ void senf::ppi::EventDescriptor::enabled(bool v) { SENF_ASSERT(v_isRegistered() && "Module::registerEvent() call missing"); + if (throttled_ && v) + return; if (v && ! enabled_) v_enable(); else if (! v && enabled_) diff --git a/PPI/Events.cci b/PPI/Events.cci index 1e50eb73390c91230693848416ed56d6df75d299..3800f201af2f1f986e7f691bf53eceae5415786c 100644 --- a/PPI/Events.cci +++ b/PPI/Events.cci @@ -44,7 +44,7 @@ prefix_ bool senf::ppi::EventDescriptor::enabled() // protected members prefix_ senf::ppi::EventDescriptor::EventDescriptor() - : enabled_(false) + : enabled_(false), throttled_(false) {} //////////////////////////////////////// @@ -52,6 +52,7 @@ prefix_ senf::ppi::EventDescriptor::EventDescriptor() prefix_ void senf::ppi::EventDescriptor::notifyThrottle() { + throttled_ = true; enabled(false); } diff --git a/PPI/Events.hh b/PPI/Events.hh index 3f2fc25b25bc694456b14ee0af70c02be97152d4..39e9d486cff61a5d86b90aada56961fd201703b6 100644 --- a/PPI/Events.hh +++ b/PPI/Events.hh @@ -87,6 +87,7 @@ namespace ppi { void registerRoute(ForwardingRoute & route); bool enabled_; + bool throttled_; typedef std::vector<ForwardingRoute*> Routes; Routes routes_; diff --git a/PPI/IOEvent.ct b/PPI/IOEvent.ct index 0f94c3c3b8a53c296550e215f2080d8859d390a2..e33c06fe9d0accd9cbf958b0e15fcaa8280bb37f 100644 --- a/PPI/IOEvent.ct +++ b/PPI/IOEvent.ct @@ -36,7 +36,10 @@ prefix_ void senf::ppi::IOEvent::set(Handle handle, unsigned events) if (handle) { fd_ = senf::scheduler::get_descriptor(handle); event_.events(events).handle(fd_); - event_.enable(); + if (enabled()) + event_.enable(); + else + event_.disable(); } else { event_.disable(); diff --git a/PPI/ModuleManager.cc b/PPI/ModuleManager.cc index 9e890b7f12ffea15a196d2195aab3422409f81ea..77f190c17eb299c5ec13346a9fd56fb2102a9ceb 100644 --- a/PPI/ModuleManager.cc +++ b/PPI/ModuleManager.cc @@ -80,7 +80,13 @@ prefix_ senf::ppi::ModuleManager::ModuleManager() .add("dump", senf::membind(&ModuleManager::dumpModules, this)) .doc("Dump complete PPI structure\n" "The dump will contain one paragraph for each module. The first line gives module\n" - "information, additional lines list all connectors and their peers (if connected)."); + "information, additional lines list all connectors and their peers (if connected).\n" + "\n" + "This information can be processed by 'PPI/drawmodules.py' and 'dot' (from the\n" + "graphviz package) to generate a graphic representation of the module structure:\n" + "\n" + " $ echo /sys/ppi/dump | nc -q1 <host> <port> \\\n" + " | python PPI/drawmodules.py | dot -Tpng /dev/fd/0 >modules.png\n"); } prefix_ void senf::ppi::ModuleManager::dumpModules(std::ostream & os) diff --git a/PPI/SocketSink.ct b/PPI/SocketSink.ct index 69726a28d44250d6ca8c8c179cada27127fbb4f0..4864625b6adf5249cf140825ea2af93db809459a 100644 --- a/PPI/SocketSink.ct +++ b/PPI/SocketSink.ct @@ -125,7 +125,7 @@ prefix_ void senf::ppi::module::PassiveSocketSink<Writer>::write() template <class Writer> prefix_ void senf::ppi::module::PassiveSocketSink<Writer>::checkThrottle() { - if (handle_) + if (handle_.valid()) input.unthrottle(); else input.throttle(); diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index 079229dbf4c1a86f570400d4dd716ed5bd987d9c..76e6d73f0c27f3e9df14bab0ed8b170e790247ee 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -377,7 +377,11 @@ template <class SPolicy> prefix_ void senf::ClientSocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod) { map["handle"] = prettyName(typeid(*this)); - this->body().state(map, lod); + if (this->valid()) { + map["valid"] << "true"; + this->body().state(map,lod); + } else + map["valid"] << "false"; } template <class SPolicy> diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti index efdb9349a20592c3ddbc11391d04916a389a06e4..1d49c702f963edc5950206da361d6e55368d7f7f 100644 --- a/Socket/ProtocolClientSocketHandle.cti +++ b/Socket/ProtocolClientSocketHandle.cti @@ -91,7 +91,11 @@ senf::ProtocolClientSocketHandle<SocketProtocol>::state(SocketStateMap & map, unsigned lod) { map["handle"] = prettyName(typeid(*this)); - this->body().state(map,lod); + if (this->valid()) { + map["valid"] << "true"; + this->body().state(map,lod); + } else + map["valid"] << "false"; } template <class SocketProtocol> diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti index 2cd77531474ef9c210eb595eaecfec51d4f3e1ab..26c2b696551c22789436a927251eb4b0d839201c 100644 --- a/Socket/ProtocolServerSocketHandle.cti +++ b/Socket/ProtocolServerSocketHandle.cti @@ -91,7 +91,11 @@ senf::ProtocolServerSocketHandle<SocketProtocol>::state(SocketStateMap & map, unsigned lod) { map["handle"] = prettyName(typeid(*this)); - this->body().state(map,lod); + if (this->valid()) { + map["valid"] << "true"; + this->body().state(map,lod); + } else + map["valid"] << "false"; } template <class SocketProtocol> diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index 132625d789786bec3248d05e9fca5d9d5d2a2e29..34b850b82e8264a6745bdd8957653933181cc0d4 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -147,7 +147,11 @@ template <class SPolicy> prefix_ void senf::ServerSocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod) { map["handle"] = prettyName(typeid(*this)); - this->body().state(map,lod); + if (this->valid()) { + map["valid"] << "true"; + this->body().state(map,lod); + } else + map["valid"] << "false"; } template <class SPolicy> diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti index 310dfddccb3cb7bd04274b358bf578d815625718..bc3f7be935f228a9256f9f7458af3bc6e7adcc88 100644 --- a/Socket/SocketHandle.cti +++ b/Socket/SocketHandle.cti @@ -175,7 +175,11 @@ prefix_ void senf::SocketHandle<SPolicy>::state(SocketStateMap & map, unsigned l // the type name and therefore show the \e static policy of the // socket handle. map["handle"] << prettyName(typeid(*this)); - body().state(map,lod); + if (valid()) { + map["valid"] << "true"; + body().state(map,lod); + } else + map["valid"] << "false"; } template <class SPolicy> diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index 66564bb019487f2e28c5bbf1dc60de831f5ccb3c..a1bad60e45e27a1a2b53e43b9e1e77e93fb57951 100644 --- a/Utils/Console/Server.cc +++ b/Utils/Console/Server.cc @@ -111,7 +111,15 @@ prefix_ void senf::console::Server::newClient(int event) prefix_ void senf::console::Server::removeClient(Client & client) { - SENF_LOG(( "Disposing client " << client.handle().peer() )); + SENF_LOG_BLOCK(({ + log << "Disposing client "; + try { + log << client.handle().peer(); + } + catch (senf::SystemException ex) { + log << "(unknown)"; + } + })); // THIS DELETES THE CLIENT INSTANCE !! clients_.erase(boost::intrusive_ptr<Client>(&client)); }