mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
multi: update timer unconditionally in multi_remove_handle
When removing an easy handle from a multi, there was an optimization to update the timer only when the removed handle had any timers. With the introduction of the "dirty" bitset, easy handles can now cause a timeout of 0 to be set without having anything in their timer list. Removing such a handle needs to update the timer now always, so that it may get cleared when there is nothing more to wait for. The previous "not clearing a 0 timer" should not have any effect on application's logic. Without clearing, the timer will fire and then adjust itself to the proper value. But it would cause one more timer fire than necessary. Reported-by: Jan Macku Fixes https://github.com/curl/curl/issues/20498 Closes https://github.com/curl/curl/pull/20502
This commit is contained in:
parent
0590753a3c
commit
2d4efbb9b3
17
lib/multi.c
17
lib/multi.c
@ -753,7 +753,6 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
bool premature;
|
||||
struct Curl_llist_node *e;
|
||||
CURLMcode mresult;
|
||||
bool removed_timer = FALSE;
|
||||
uint32_t mid;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
@ -808,7 +807,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
/* The timer must be shut down before data->multi is set to NULL, else the
|
||||
timenode will remain in the splay tree after curl_easy_cleanup is
|
||||
called. Do it after multi_done() in case that sets another time! */
|
||||
removed_timer = Curl_expire_clear(data);
|
||||
Curl_expire_clear(data);
|
||||
|
||||
/* If in `msgsent`, it was deducted from `multi->xfers_alive` already. */
|
||||
if(!Curl_uint32_bset_contains(&multi->msgsent, data->mid))
|
||||
@ -881,11 +880,9 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
We do not touch the easy handle here! */
|
||||
process_pending_handles(multi);
|
||||
|
||||
if(removed_timer) {
|
||||
mresult = Curl_update_timer(multi);
|
||||
if(mresult)
|
||||
return mresult;
|
||||
}
|
||||
mresult = Curl_update_timer(multi);
|
||||
if(mresult)
|
||||
return mresult;
|
||||
|
||||
CURL_TRC_M(data, "removed from multi, mid=%u, running=%u, total=%u",
|
||||
mid, Curl_multi_xfers_running(multi),
|
||||
@ -3604,7 +3601,7 @@ void Curl_expire_done(struct Curl_easy *data, expire_id eid)
|
||||
*
|
||||
* Clear ALL timeout values for this handle.
|
||||
*/
|
||||
bool Curl_expire_clear(struct Curl_easy *data)
|
||||
void Curl_expire_clear(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_multi *multi = data->multi;
|
||||
struct curltime *nowp = &data->state.expiretime;
|
||||
@ -3612,7 +3609,7 @@ bool Curl_expire_clear(struct Curl_easy *data)
|
||||
/* this is only interesting while there is still an associated multi struct
|
||||
remaining! */
|
||||
if(!multi)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
@ -3632,9 +3629,7 @@ bool Curl_expire_clear(struct Curl_easy *data)
|
||||
CURL_TRC_M(data, "[TIMEOUT] all cleared");
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_assign(CURLM *m, curl_socket_t s,
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
|
||||
void Curl_expire_ex(struct Curl_easy *data,
|
||||
timediff_t milli, expire_id id);
|
||||
bool Curl_expire_clear(struct Curl_easy *data);
|
||||
void Curl_expire_clear(struct Curl_easy *data);
|
||||
void Curl_expire_done(struct Curl_easy *data, expire_id id);
|
||||
CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT;
|
||||
void Curl_attach_connection(struct Curl_easy *data,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user