diff options
author | Daniel Stenberg <daniel@haxx.se> | 2019-07-29 13:41:00 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-08-06 09:33:29 +0200 |
commit | 02346abc32a3995299fa9c2f35b9f0a1d091b045 (patch) | |
tree | de504a328c326fc2ebef7265ddf4de7456fd56be /src | |
parent | cee7639b790f29113759f69c4a955c2ead8bff31 (diff) |
curl_multi_poll: a sister to curl_multi_wait() that waits more
Repeatedly we see problems where using curl_multi_wait() is difficult or
just awkward because if it has no file descriptor to wait for
internally, it returns immediately and leaves it to the caller to wait
for a small amount of time in order to avoid occasional busy-looping.
This is often missed or misunderstood, leading to underperforming
applications.
This change introduces curl_multi_poll() as a replacement drop-in
function that accepts the exact same set of arguments. This function
works identically to curl_multi_wait() - EXCEPT - for the case when
there's nothing to wait for internally, as then this function will by
itself wait for a "suitable" short time before it returns. This
effectiely avoids all risks of busy-looping and should also make it less
likely that apps "over-wait".
This also changes the curl tool to use this funtion internally when
doing parallel transfers and changes curl_easy_perform() to use it
internally.
Closes #4163
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_operate.c | 42 |
1 files changed, 2 insertions, 40 deletions
diff --git a/src/tool_operate.c b/src/tool_operate.c index 7cb2f01f9..946dc7cca 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1904,23 +1904,6 @@ static CURLcode create_transfers(struct GlobalConfig *global, return result; } -/* portable millisecond sleep */ -static void wait_ms(int ms) -{ -#if defined(MSDOS) - delay(ms); -#elif defined(WIN32) - Sleep(ms); -#elif defined(HAVE_USLEEP) - usleep(1000 * ms); -#else - struct timeval pending_tv; - pending_tv.tv_sec = ms / 1000; - pending_tv.tv_usec = (ms % 1000) * 1000; - (void)select(0, NULL, NULL, NULL, &pending_tv); -#endif -} - static long all_added; /* number of easy handles currently added */ static int add_parallel_transfers(struct GlobalConfig *global, @@ -1971,30 +1954,9 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, return result; while(!done && !mcode && still_running) { - int numfds; - struct timeval before = tvnow(); - long delta; - - mcode = curl_multi_wait(multi, NULL, 0, 1000, &numfds); - delta = tvdiff(tvnow(), before); - - if(!mcode) { - if(!numfds && (delta < 30)) { - long sleep_ms; - - /* If it returns without any file descriptor instantly, we need to - avoid busy-looping during periods where it has nothing particular - to wait for */ - curl_multi_timeout(multi, &sleep_ms); - if(sleep_ms) { - if(sleep_ms > 1000) - sleep_ms = 1000; - wait_ms((int)sleep_ms); - } - } - + mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); + if(!mcode) mcode = curl_multi_perform(multi, &still_running); - } progress_meter(global, &start, FALSE); |