multi: enhance pending handles fairness
No binary (build failed)
—
(log yok)
| @@ -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 */ | |