diff options
author | Daniel Stenberg <daniel@haxx.se> | 2019-09-10 13:37:38 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-09-10 19:45:19 +0200 |
commit | bbde0407d1e3750cfc161615491420217b718994 (patch) | |
tree | e365609cf1dc05ea24f4a236c469b7d7f5bb10c3 /src | |
parent | 9637dbfffdb42f5478cf8c0afe337f559513a7fe (diff) |
curl: make sure the parallel transfers do them all
The logic could erroneously break the loop too early before all
transfers had been transferred.
Reported-by: Tom van der Woerdt
Fixes #4316
Closes #4317
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_operate.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/tool_operate.c b/src/tool_operate.c index 9b5225853..d2ad9642d 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1924,12 +1924,21 @@ static CURLcode create_transfers(struct GlobalConfig *global, static long all_added; /* number of easy handles currently added */ +/* + * add_parallel_transfers() sets 'morep' to TRUE if there are more transfers + * to add even after this call returns. sets 'addedp' to TRUE if one or more + * transfers were added. + */ static int add_parallel_transfers(struct GlobalConfig *global, - CURLM *multi) + CURLM *multi, + bool *morep, + bool *addedp) { struct per_transfer *per; CURLcode result; CURLMcode mcode; + *addedp = FALSE; + *morep = FALSE; for(per = transfers; per && (all_added < global->parallel_max); per = per->next) { if(per->added) @@ -1949,7 +1958,9 @@ static int add_parallel_transfers(struct GlobalConfig *global, return CURLE_OUT_OF_MEMORY; per->added = TRUE; all_added++; + *addedp = TRUE; } + *morep = per ? TRUE : FALSE; return CURLE_OK; } @@ -1962,16 +1973,19 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, CURLcode result = CURLE_OK; int still_running = 1; struct timeval start = tvnow(); + bool more_transfers; + bool added_transfers; multi = curl_multi_init(); if(!multi) return CURLE_OUT_OF_MEMORY; - result = add_parallel_transfers(global, multi); + result = add_parallel_transfers(global, multi, + &more_transfers, &added_transfers); if(result) return result; - while(!done && !mcode && still_running) { + while(!done && !mcode && (still_running || more_transfers)) { mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); if(!mcode) mcode = curl_multi_perform(multi, &still_running); @@ -2001,9 +2015,14 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, (void)del_transfer(ended); } } while(msg); - if(removed) + if(removed) { /* one or more transfers completed, add more! */ - (void)add_parallel_transfers(global, multi); + (void)add_parallel_transfers(global, multi, &more_transfers, + &added_transfers); + if(added_transfers) + /* we added new ones, make sure the loop doesn't exit yet */ + still_running = 1; + } } } |