mirror of
https://github.com/curl/curl.git
synced 2026-05-04 15:19:55 +03:00
multi: enhance pending handles fairness
When trying to connect a pending transfer, remember the `mid` that was last reactivated and start looking for future pending handles from the last one forward through the pending bitset. Background: when many pending handles exist, iterating the bitset always from the start may become unfair to transfers that were assigned higher `mid` values. Fixes #21396 Reported-by: Juan Belón Closes #21412
This commit is contained in:
parent
d6372e60e5
commit
00cac453c7
2 changed files with 22 additions and 2 deletions
23
lib/multi.c
23
lib/multi.c
|
|
@ -3760,13 +3760,32 @@ static void move_pending_to_connect(struct Curl_multi *multi,
|
|||
*/
|
||||
static void process_pending_handles(struct Curl_multi *multi)
|
||||
{
|
||||
uint32_t mid;
|
||||
uint32_t mid = multi->last_pending_mid;
|
||||
|
||||
if(mid) {
|
||||
while(Curl_uint32_bset_next(&multi->pending, mid, &mid)) {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
move_pending_to_connect(multi, data);
|
||||
multi->last_pending_mid = mid;
|
||||
return;
|
||||
}
|
||||
/* transfer no longer known, should not happen */
|
||||
Curl_uint32_bset_remove(&multi->pending, mid);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
/* found no pending transfers with `mid` larger than `last_pending_mid`.
|
||||
* Start at the beginning of the pending set again. */
|
||||
multi->last_pending_mid = 0;
|
||||
}
|
||||
|
||||
if(Curl_uint32_bset_first(&multi->pending, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
move_pending_to_connect(multi, data);
|
||||
break;
|
||||
multi->last_pending_mid = mid;
|
||||
return;
|
||||
}
|
||||
/* transfer no longer known, should not happen */
|
||||
Curl_uint32_bset_remove(&multi->pending, mid);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ struct Curl_multi {
|
|||
#ifdef DEBUGBUILD
|
||||
unsigned int now_access_count;
|
||||
#endif
|
||||
uint32_t last_pending_mid; /* mid of last pending transfer rescheduled */
|
||||
uint32_t last_resolv_id; /* id of the last DNS resolve operation */
|
||||
BIT(ipv6_works);
|
||||
BIT(multiplexing); /* multiplexing wanted */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue