|
|
cURL Mailing List Monthly Index Single Mail
curl-tracker Archives
[curl:bugs] #1298 libcurl will be hang with libevent when timeout
From: Daniel Stenberg <bagder_at_users.sf.net>
Date: Tue, 03 Dec 2013 12:38:18 +0000
I think you're looking at the problem and solution too narrowly and for your specific case only.
The reason for the timeout inaccuracy define in the first place is that timers provided by operating systems and event libraries are imprecise. Most timers have a small time window during which it can trigger, which starts slightly *before* the given timeout. On some systems this is bigger than on others.
So, we need to handle this case. We have lib/multi.c:multi_socket() run timeouts that "soon" expires, but it isn't working properly since we have fixed limits elsewhere like in your case basically the Curl_timeleft() or similar.
In your specific case we can possibly adjust the code ever so slightly slightly so that we push some microseconds to make the math then round to 80 instead of 79, but I don't consider that to be a complete and solid fix for the general problem we have with this timeout check.
--- ** [bugs:#1298] libcurl will be hang with libevent when timeout** **Status:** open-confirmed **Created:** Fri Nov 08, 2013 10:24 AM UTC by he qin **Last Updated:** Mon Dec 02, 2013 02:38 PM UTC **Owner:** Daniel Stenberg hi, I use libcurl & libevent to build a project (like docs/examples/hiperfifo.c) . I found that the easy handle will be hang in some case such as network timeout. After reading the libcurl code and testing, I found the reason is libcurl control the timeout is not exact. This is my case: 1. set easy handle timeout is 80ms. 2. add easy handle to multi 3. when multi called the sock_cb, set the event, and set the timeout(80ms) 4. network timeout (easy handle read timeout) 5. libevent tell the curl timeout and curl call multi_socket function. 6. in multi_socket function, add_next_timeout will be called at last few line, and It will clean the timeoutlist for this easy handle because timeout occur. (at this moment, the easy hanle's state is CURLM_STATE_PERFORM) 7. next, it will call multi_runsingle function to process this easy handle, but in multi_runsingle function, Curl_timeleft will be called to check timeout occur or not. in Curl_timeleft it used the (now - t_startsingle). pay attention to this point, this may be 1ms, because Curl_tvdiff is not exact, such as : now(46151672,246084) - t_startsingle(46151672,166088) = 79ms, timeout is 80ms, so 80 - 79 = 1ms. 8. next, libcurl will be think this easy handle not timeout, but actually timeout occur, and the timeoutlist was cleared, so it will never be woke up. this easy handle will be hang for ever. I think the logic for this code, I found that the real reason is that "Curl_pgrsTime(data, TIMER_STARTSINGLE);" be called after "Curl_expire(data, data->set.timeout);" . I try to move the "Curl_pgrsTime(data, TIMER_STARTSINGLE);" before ""Curl_expire(data, data->set.timeout);" , the bad case never occur. In a word, call the timer before set t_startsingle, will let libevet premature wake up the libcurl to process, and libcurl will think this not timeout. of course, this bad case will occur fewly, but when this occur, the result will be very terrible. --- Sent from sourceforge.net because curl-tracker@cool.haxx.se is subscribed to https://sourceforge.net/p/curl/bugs/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/curl/admin/bugs/options. Or, if this is a mailing list, you can unsubscribe from the mailing list.Received on 2013-12-03 These mail archives are generated by hypermail. |
Page updated May 06, 2013.
web site info