From: Alex Rousskov Date: Mon, 2 Jun 2014 05:09:38 +0000 (-0700) Subject: Fix leaked TcpAcceptor job on reconfiguration X-Git-Tag: SQUID_3_5_0_1~213 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f09127ce03e36b0a5ac7be45d0fd11c15875f71;p=thirdparty%2Fsquid.git Fix leaked TcpAcceptor job on reconfiguration ... by monitoring and reacting to the listening socket closure. Every job that waits for Comm I/O must have a FD closure handler. --- diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 4e0dfbbc0c..44a6c8263a 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -122,6 +122,12 @@ Comm::TcpAcceptor::swanSong() { debugs(5,5, HERE); unsubscribe("swanSong"); + if (IsConnOpen(conn)) { + if (closer_ != NULL) + comm_remove_close_handler(conn->fd, closer_); + conn->close(); + } + conn = NULL; AcceptLimiter::Instance().removeDead(this); AsyncJob::swanSong(); @@ -182,6 +188,20 @@ Comm::TcpAcceptor::setListen() debugs(5, DBG_CRITICAL, "WARNING: accept_filter not supported on your OS"); #endif } + + typedef CommCbMemFunT Dialer; + closer_ = JobCallback(5, 4, Dialer, this, Comm::TcpAcceptor::handleClosure); + comm_add_close_handler(conn->fd, closer_); +} + +/// called when listening descriptor is closed by an external force +/// such as clientHttpConnectionsClose() +void +Comm::TcpAcceptor::handleClosure(const CommCloseCbParams &io) +{ + closer_ = NULL; + conn = NULL; + Must(done()); } /** diff --git a/src/comm/TcpAcceptor.h b/src/comm/TcpAcceptor.h index ee3b392cd1..4ab9e9e309 100644 --- a/src/comm/TcpAcceptor.h +++ b/src/comm/TcpAcceptor.h @@ -7,6 +7,8 @@ #include "comm/forward.h" #include "comm_err_t.h" +class CommCloseCbParams; + namespace Comm { @@ -73,6 +75,9 @@ private: /// Reserved for read-only use. ConnectionPointer conn; + /// listen socket closure handler + AsyncCall::Pointer closer_; + /// Method to test if there are enough file descriptors to open a new client connection /// if not the accept() will be postponed static bool okToAccept(); @@ -83,6 +88,7 @@ private: void acceptOne(); comm_err_t oldAccept(Comm::ConnectionPointer &details); void setListen(); + void handleClosure(const CommCloseCbParams &io); CBDATA_CLASS2(TcpAcceptor); };