From: Alex Rousskov Date: Tue, 3 Jun 2014 07:10:15 +0000 (-0600) Subject: Fix leaked TcpAcceptor job on reconfiguration X-Git-Tag: SQUID_3_4_6~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7552d310f304af6c26d17c95a6a66bdfba6b367f;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 0e703024fd..5582c37ced 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 48aee211ee..3ca2a9773a 100644 --- a/src/comm/TcpAcceptor.h +++ b/src/comm/TcpAcceptor.h @@ -7,6 +7,8 @@ #include "comm_err_t.h" #include "comm/forward.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); };