On Thursday, August 12, 2010 02:51:50 am Daniel Stenberg wrote:
> >> And to be specific, can you please tell me exactly what bug and what
> >> bugfix you're talking about?
> > 
> > It is documented in libcurl as "known bug #62", and the last fix patch in
> > message id <[email protected]>
> 
> As far as I remember, we've never had a non-contriversial and complete
> patch for that problem. Can you provide the patch again please?

Attached. One person had some compiler compatibility change suggestions, which 
was before the -r2 version of this patch. After that, one person wrote that it 
"works fine, passes all tests, but it is still plain wrong" but never came up 
with any real technical reasons *why* it was wrong.

> I have however written my own fix for the known bug #62 as I mentioned in
> my post and patch series I posted here the other day:
> 
>       http://curl.haxx.se/mail/lib-2010-08/0117.html
> 
> ... and I didn't see any comments from anyone on that (yet).

I'll look into testing this...
? a
? libcurl-fix-multi-timeouts-r2.patch
? libcurl-fix-multi-timeouts.patch
Index: lib/multi.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/multi.c,v
retrieving revision 1.198
diff -u -r1.198 multi.c
--- lib/multi.c	11 May 2009 07:53:38 -0000	1.198
+++ lib/multi.c	13 May 2009 15:21:14 -0000
@@ -26,6 +26,9 @@
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -887,6 +890,34 @@
   return CURLM_OK;
 }
 
+static void update_timeout(struct SessionHandle *data)
+{
+  struct timeval now, start;
+  long timeout, passed, remaining;
+
+  now = Curl_tvnow();
+  start = data->req.start;
+  if (!start.tv_sec && !start.tv_usec)
+  {
+    /* FIXME: Should we recalculate timeout again later? */
+    Curl_expire(data, 0);
+    return;
+  }
+
+  timeout = data->set.timeout;
+  passed = curlx_tvdiff(now, start);
+  if (passed > timeout) {
+    /* Timeout occurs in the past */
+    /* FIXME: what if the timeout hasn't be processed yet? */
+    Curl_expire(data, 0);
+    return;
+  }
+  --passed;  /* round any sub-ms delay up */
+
+  remaining = timeout - passed;
+  Curl_expire(data, remaining);
+}
+
 static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                  struct Curl_one_easy *easy)
 {
@@ -936,6 +967,7 @@
       easy->result=Curl_pretransfer(easy->easy_handle);
 
       if(CURLE_OK == easy->result) {
+        update_timeout(easy->easy_handle);
         /* after init, go CONNECT */
         multistate(easy, CURLM_STATE_CONNECT);
         result = CURLM_CALL_MULTI_PERFORM;
@@ -1537,6 +1569,8 @@
          splay tree */
       tv->tv_sec = 0;
       tv->tv_usec = 0;
+
+      update_timeout(d);
     }
 
   } while(t);
@@ -1909,6 +1943,8 @@
         /* get the socket(s) and check if the state has been changed since
            last */
         singlesocket(multi, data->set.one_easy);
+
+        update_timeout(data);
     }
 
     /* Check if there's one (more) expired timer to deal with! This function
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to