]> granicus.if.org Git - curl/commitdiff
multi_socket: reduce timeout inaccuracy margin
authorDaniel Stenberg <daniel@haxx.se>
Mon, 10 Jun 2013 08:09:16 +0000 (10:09 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 10 Jun 2013 22:02:29 +0000 (00:02 +0200)
Allow less room for "triggered too early" mistakes by applications /
timers on non-windows platforms. Starting now, we assume that a timeout
call is never made earlier than 3 milliseconds before the actual
timeout. This greatly improves timeout accuracy on Linux.

Bug: http://curl.haxx.se/bug/view.cgi?id=1228
Reported-by: Hang Su
lib/multi.c

index 12c6a344b14026b8338c65e04b81ee4daa8c1d89..25efce154a7e1aa78ddf0dba9ecb5f746a470352 100644 (file)
@@ -2106,6 +2106,11 @@ static CURLMcode add_next_timeout(struct timeval now,
   return CURLM_OK;
 }
 
+#ifdef WIN32
+#define TIMEOUT_INACCURACY 40000
+#else
+#define TIMEOUT_INACCURACY 3000
+#endif
 
 static CURLMcode multi_socket(struct Curl_multi *multi,
                               bool checkall,
@@ -2195,8 +2200,25 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
     }
   }
 
-  now.tv_usec += 40000; /* compensate for bad precision timers that might've
-                           triggered too early */
+  /* Compensate for bad precision timers that might've triggered too early.
+
+     This precaution was added in commit 2c72732ebf3da5e as a result of bad
+     resolution in the windows function use(d).
+
+     The problematic case here is when using the multi_socket API and libcurl
+     has told the application about a timeout, and that timeout is what fires
+     off a bit early. As we don't have any IDs associated with the timeout we
+     can't tell which timeout that fired off but we only have the times to use
+     to check what to do. If it fires off too early, we don't run the correct
+     actions and we don't tell the application again about the same timeout as
+     was already first in the queue...
+
+     Originally we made the timeouts run 40 milliseconds early on all systems,
+     but now we have an #ifdef setup to provide a decent precaution inaccuracy
+     margin.
+  */
+
+  now.tv_usec += TIMEOUT_INACCURACY;
   if(now.tv_usec >= 1000000) {
     now.tv_sec++;
     now.tv_usec -= 1000000;