From: g0dil Date: Thu, 13 Aug 2009 12:42:42 +0000 (+0000) Subject: Socket: Fix handle.state() on invalid handles X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=d5a72d0b3f6fee56dba6de1c54cafb448ebe3457;p=senf.git Socket: Fix handle.state() on invalid handles Utils/Console: Catch exceptions when closing client PPI: Add throttle tracing PPI: Fix Event and IOEvent throttling git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1291 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/PPI/Connectors.cc b/PPI/Connectors.cc index cf241d5..ce44e0d 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: \n" + " PPI packet trace: \n" + " on connector \n" + " PPI throttling trace: \n" " on connector \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 f480b02..ec587ce 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 002154e..e6b8c07 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 3525d3d..7aa0298 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 1e50eb7..3800f20 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 3f2fc25..39e9d48 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 Routes; Routes routes_; diff --git a/PPI/IOEvent.ct b/PPI/IOEvent.ct index 0f94c3c..e33c06f 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 9e890b7..77f190c 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 \\\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 69726a2..4864625 100644 --- a/PPI/SocketSink.ct +++ b/PPI/SocketSink.ct @@ -125,7 +125,7 @@ prefix_ void senf::ppi::module::PassiveSocketSink::write() template prefix_ void senf::ppi::module::PassiveSocketSink::checkThrottle() { - if (handle_) + if (handle_.valid()) input.unthrottle(); else input.throttle(); diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index 079229d..76e6d73 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -377,7 +377,11 @@ template prefix_ void senf::ClientSocketHandle::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 diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti index efdb934..1d49c70 100644 --- a/Socket/ProtocolClientSocketHandle.cti +++ b/Socket/ProtocolClientSocketHandle.cti @@ -91,7 +91,11 @@ senf::ProtocolClientSocketHandle::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 diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti index 2cd7753..26c2b69 100644 --- a/Socket/ProtocolServerSocketHandle.cti +++ b/Socket/ProtocolServerSocketHandle.cti @@ -91,7 +91,11 @@ senf::ProtocolServerSocketHandle::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 diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index 132625d..34b850b 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -147,7 +147,11 @@ template prefix_ void senf::ServerSocketHandle::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 diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti index 310dfdd..bc3f7be 100644 --- a/Socket/SocketHandle.cti +++ b/Socket/SocketHandle.cti @@ -175,7 +175,11 @@ prefix_ void senf::SocketHandle::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 diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index 66564bb..a1bad60 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)); }