mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
multi: fix condition that remove timers before trigger
curl_multi perform has two phases: run through every easy handle calling multi_runsingle and remove expired timers (timer removal). If a small timer (e.g. 1-10ms) is set during multi_runsingle, then it's possible that the timer has passed by when the timer removal runs. The timer which was just added is then removed. This will potentially cause the timer list to be empty and cause the next call to curl_multi_timeout to return -1. Ideally, curl_multi_timeout should return 0 in this case. One way to fix this is to move the struct timeval now = Curl_tvnow(); to the top of curl_multi_perform. The change does that.
This commit is contained in:
parent
3992309285
commit
d4e6404135
@ -1570,6 +1570,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
struct Curl_one_easy *easy;
|
struct Curl_one_easy *easy;
|
||||||
CURLMcode returncode=CURLM_OK;
|
CURLMcode returncode=CURLM_OK;
|
||||||
struct Curl_tree *t;
|
struct Curl_tree *t;
|
||||||
|
struct timeval now = Curl_tvnow();
|
||||||
|
|
||||||
if(!GOOD_MULTI_HANDLE(multi))
|
if(!GOOD_MULTI_HANDLE(multi))
|
||||||
return CURLM_BAD_HANDLE;
|
return CURLM_BAD_HANDLE;
|
||||||
@ -1607,10 +1608,13 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
* Simply remove all expired timers from the splay since handles are dealt
|
* Simply remove all expired timers from the splay since handles are dealt
|
||||||
* with unconditionally by this function and curl_multi_timeout() requires
|
* with unconditionally by this function and curl_multi_timeout() requires
|
||||||
* that already passed/handled expire times are removed from the splay.
|
* that already passed/handled expire times are removed from the splay.
|
||||||
|
*
|
||||||
|
* It is important that the 'now' value is set at the entry of this function
|
||||||
|
* and not for the current time as it may have ticked a little while since
|
||||||
|
* then and then we risk this loop to remove timers that actually have not
|
||||||
|
* been handled!
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
struct timeval now = Curl_tvnow();
|
|
||||||
|
|
||||||
multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
|
multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
|
||||||
if(t) {
|
if(t) {
|
||||||
struct SessionHandle *d = t->payload;
|
struct SessionHandle *d = t->payload;
|
||||||
|
Loading…
Reference in New Issue
Block a user