examples/10-at-a-time: fix possible skipped final transfers

Prior to this change if curl_multi_perform returned 0 running handles
and then all remaining transfers were added, then the perform loop would
end immediately without performing those transfers.

Reported-by: Mikhail Kuznetsov

Fixes https://github.com/curl/curl/issues/9953
Closes https://github.com/curl/curl/pull/9954
This commit is contained in:
Daniel Stenberg 2022-11-22 03:32:42 -05:00 коммит произвёл Jay Satiro
Родитель a8861b6ccd
Коммит a28a80d59e
1 изменённых файлов: 11 добавлений и 7 удалений

Просмотреть файл

@ -95,13 +95,14 @@ static size_t write_cb(char *data, size_t n, size_t l, void *userp)
return n*l;
}
static void add_transfer(CURLM *cm, int i)
static void add_transfer(CURLM *cm, int i, int *left)
{
CURL *eh = curl_easy_init();
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
curl_multi_add_handle(cm, eh);
(*left)++;
}
int main(void)
@ -110,7 +111,7 @@ int main(void)
CURLMsg *msg;
unsigned int transfers = 0;
int msgs_left = -1;
int still_alive = 1;
int left = 0;
curl_global_init(CURL_GLOBAL_ALL);
cm = curl_multi_init();
@ -118,10 +119,12 @@ int main(void)
/* Limit the amount of simultaneous connections curl should allow: */
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL);
for(transfers = 0; transfers < MAX_PARALLEL; transfers++)
add_transfer(cm, transfers);
for(transfers = 0; transfers < MAX_PARALLEL && transfers < NUM_URLS;
transfers++)
add_transfer(cm, transfers, &left);
do {
int still_alive = 1;
curl_multi_perform(cm, &still_alive);
while((msg = curl_multi_info_read(cm, &msgs_left))) {
@ -133,17 +136,18 @@ int main(void)
msg->data.result, curl_easy_strerror(msg->data.result), url);
curl_multi_remove_handle(cm, e);
curl_easy_cleanup(e);
left--;
}
else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
}
if(transfers < NUM_URLS)
add_transfer(cm, transfers++);
add_transfer(cm, transfers++, &left);
}
if(still_alive)
if(left)
curl_multi_wait(cm, NULL, 0, 1000, NULL);
} while(still_alive || (transfers < NUM_URLS));
} while(left);
curl_multi_cleanup(cm);
curl_global_cleanup();