cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curl-tracker Archives

[curl:bugs] Re: #1228 curl multi timeout does not work with timeout set less than 40ms

From: Hang <churinga667_at_users.sf.net>
Date: Thu, 23 May 2013 17:43:06 +0000

Daniel, Thanks for your prompt reply.
First, I want to have a clear idea about the timeout mechanism. If I understand correctly, the extra 40ms added is used to *make sure* timeout takes place, even if the timer function returns prematurely (e.g. due to a bad precision timer). For example, if the precision timer is of poor accuracy, and returns 5ms prior to the timeout_ms set by the timer function, then by adding this 40ms, we can be sure timeout still takes place. Am I understanding it correctly?

If so, I think it is a matter of granularity of timeout precision control. For modern hardware and Linux kernel, system calls like get_clocktime or even gettimeofday could yield precision better than 1ms. So, the least we can do is provide the user an option to customize this 40ms value, either as a macro (which can be overridden at build time), or as a curl easy option.

Another question that I have: if we change this 40ms to something like 2ms (or even 1ms), and we indeed encounter a bad precision timer, which returns 5ms earlier, then does libcurl adjust its expectation correctly and set another timeout timer with the difference (by calling the timer function again)? Or does libcurl simply ignores the timeout event and does not adjust the timer?

Thanks!

---
** [bugs:#1228] curl multi timeout does not work with timeout set less than 40ms**
**Status:** open
**Created:** Wed May 22, 2013 09:45 PM UTC by Hang
**Last Updated:** Thu May 23, 2013 04:41 PM UTC
**Owner:** Daniel Stenberg
In the latest source code lib/multi.c:
~~~~
2178   now.tv_usec += 40000; /* compensate for bad precision timers that might've
2179                            triggered too early */
2180   if(now.tv_usec >= 1000000) {
2181     now.tv_sec++;
2182     now.tv_usec -= 1000000;
2183   }
2184 
2185   /*
2186    * The loop following here will go on as long as there are expire-times left
2187    * to process in the splay and 'data' will be re-assigned for every expired
2188    * handle we deal with.
2189    */
2190   do {
2191     /* the first loop lap 'data' can be NULL */
2192     if(data) {
2193       do
2194         result = multi_runsingle(multi, now, data->set.one_easy);
2195       while(CURLM_CALL_MULTI_PERFORM == result);
~~~~
"now" has been artificially incremented by 40ms, and then passed in to the multi_runsingle(...) below. 
Then, multi_runsingle() will check for timeouts:
~~~~
964       timeout_ms = Curl_timeleft(data, &now,
965                                  (easy->state <= CURLM_STATE_WAITDO)?
966                                  TRUE:FALSE);
~~~~
so, if the timeout setting is less than 40ms for the curl easy handle, the Curl_tvdiff(*nowp, data->progress.t_startsingle) will return 39ms at the very beginning of the curl easy request, and therefore timeout the request even before it gets started. 
It will always prompt something like this (almost immediately after the first curl_multi_perform() call):
http://foo.com => (28) Connection timed out after 39 milliseconds
---
Sent from sourceforge.net because you indicated interest in <https://sourceforge.net/p/curl/bugs/1228/>
To unsubscribe from further messages, please visit <https://sourceforge.net/auth/subscriptions/>
Received on 2013-05-23

These mail archives are generated by hypermail.

donate! Page updated May 06, 2013.
web site info

File upload with ASP.NET