Skip to content
Permalink
Browse files

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
  • Loading branch information...
bagder committed Sep 10, 2019
1 parent 9637dbf commit bbde0407d1e3750cfc161615491420217b718994
Showing with 24 additions and 5 deletions.
  1. +24 −5 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;
}
}
}

0 comments on commit bbde040

Please sign in to comment.
You can’t perform that action at this time.