aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2019-07-29 13:41:00 +0200
committerDaniel Stenberg <daniel@haxx.se>2019-08-06 09:33:29 +0200
commit02346abc32a3995299fa9c2f35b9f0a1d091b045 (patch)
treede504a328c326fc2ebef7265ddf4de7456fd56be /src
parentcee7639b790f29113759f69c4a955c2ead8bff31 (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.c42
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);