--- mad-squid-timeout/src/comm/ConnOpener.cc 8 Jan 2013 17:36:44 -0000 1.1.1.2 +++ mad-squid-timeout/src/comm/ConnOpener.cc 21 Jan 2013 16:48:02 -0000 1.1.1.2.6.4 @@ -242,16 +242,8 @@ switch (comm_connect_addr(temporaryFd_, conn_->remote) ) { case COMM_INPROGRESS: - // check for timeout FIRST. - if (squid_curtime - connectStart_ > connectTimeout_) { - debugs(5, 5, HERE << conn_ << ": * - ERR took too long already."); - calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out"); - doneConnecting(COMM_TIMEOUT, errno); - return; - } else { - debugs(5, 5, HERE << conn_ << ": COMM_INPROGRESS"); - Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, Comm::ConnOpener::InProgressConnectRetry, new Pointer(this), 0); - } + debugs(5, 5, HERE << conn_ << ": COMM_INPROGRESS"); + Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, Comm::ConnOpener::InProgressConnectRetry, new Pointer(this), 0); break; case COMM_OK: @@ -263,12 +255,7 @@ default: ++failRetries_; - // check for timeout FIRST. - if (squid_curtime - connectStart_ > connectTimeout_) { - debugs(5, 5, HERE << conn_ << ": * - ERR took too long to receive response."); - calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out"); - doneConnecting(COMM_TIMEOUT, errno); - } else if (failRetries_ < Config.connect_retries) { + if (failRetries_ < Config.connect_retries) { debugs(5, 5, HERE << conn_ << ": * - try again"); eventAdd("Comm::ConnOpener::DelayedConnectRetry", Comm::ConnOpener::DelayedConnectRetry, new Pointer(this), 0.05, 0, false); return; @@ -319,7 +306,31 @@ void Comm::ConnOpener::timeout(const CommTimeoutCbParams &) { - connect(); + debugs(5, 5, HERE << conn_ << ": * - ERR took too long to receive response."); + + if (temporaryFd_ >= 0) { + fde *F = &fd_table[temporaryFd_]; + if (F->write_handler) { + // XXX: connect method installed a write handler + // after a successful non-blocking connect. + // Since this handler is not going to be called + // and Comm::SetSelect is not (yet) 'smart pointer + // aware', the Pointer object needs to be + // destroyed explicitly here to prevent the ConnOpener + // object from being leaked. + // + Pointer *ptr = static_cast(F->write_data); + delete ptr; + F->write_data = NULL; + Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, NULL, NULL, 0); + } + + calls_.earlyAbort_->cancel("Comm::ConnOpener::connect timed out"); + } + + calls_.timeout_ = NULL; + + doneConnecting(COMM_TIMEOUT, ETIMEDOUT); } /* Legacy Wrapper for the retry event after COMM_INPROGRESS