Amos Jeffries <[email protected]> writes:

> On 21/01/2013 9:21 a.m., Rainer Weikusat wrote:
>> The attached patch removes the timeout checking code from
>> ConnOpener::connect and

[...]

> the definitions of *F and *prt need to be inside their
> relevant if() scopes.
--- 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<Pointer *>(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

Reply via email to