You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.4 KiB
74 lines
2.4 KiB
From d3036f34cce421990e8268ee4bbfc0d9f5ceb054 Mon Sep 17 00:00:00 2001 |
|
From: Daniel Stenberg <daniel@haxx.se> |
|
Date: Thu, 13 Jun 2013 19:27:12 +0200 |
|
Subject: [PATCH] curl_easy_perform: avoid busy-looping |
|
|
|
When curl_multi_wait() finds no file descriptor to wait for, it returns |
|
instantly and this must be handled gracefully within curl_easy_perform() |
|
or cause a busy-loop. Starting now, repeated fast returns without any |
|
file descriptors is detected and a gradually increasing sleep will be |
|
used (up to a max of 1000 milliseconds) before continuing the loop. |
|
|
|
Bug: http://curl.haxx.se/bug/view.cgi?id=1238 |
|
Reported-by: Miguel Angel |
|
|
|
[upstream commit 0feeab7802dd2a6465d22d153d8d36b2cca99b96] |
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com> |
|
--- |
|
lib/easy.c | 25 +++++++++++++++++++++++++ |
|
1 files changed, 25 insertions(+), 0 deletions(-) |
|
|
|
diff --git a/lib/easy.c b/lib/easy.c |
|
index 2739598..a7051dd 100644 |
|
--- a/lib/easy.c |
|
+++ b/lib/easy.c |
|
@@ -410,6 +410,9 @@ CURLcode curl_easy_perform(CURL *easy) |
|
bool done = FALSE; |
|
int rc; |
|
struct SessionHandle *data = easy; |
|
+ int without_fds = 0; /* count number of consecutive returns from |
|
+ curl_multi_wait() without any filedescriptors */ |
|
+ struct timeval before; |
|
|
|
if(!easy) |
|
return CURLE_BAD_FUNCTION_ARGUMENT; |
|
@@ -445,6 +448,7 @@ CURLcode curl_easy_perform(CURL *easy) |
|
int still_running; |
|
int ret; |
|
|
|
+ before = curlx_tvnow(); |
|
mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret); |
|
|
|
if(mcode == CURLM_OK) { |
|
@@ -453,6 +457,27 @@ CURLcode curl_easy_perform(CURL *easy) |
|
code = CURLE_RECV_ERROR; |
|
break; |
|
} |
|
+ else if(ret == 0) { |
|
+ struct timeval after = curlx_tvnow(); |
|
+ /* If it returns without any filedescriptor instantly, we need to |
|
+ avoid busy-looping during periods where it has nothing particular |
|
+ to wait for */ |
|
+ if(curlx_tvdiff(after, before) <= 10) { |
|
+ without_fds++; |
|
+ if(without_fds > 2) { |
|
+ int sleep_ms = without_fds * 50; |
|
+ if(sleep_ms > 1000) |
|
+ sleep_ms = 1000; |
|
+ Curl_wait_ms(sleep_ms); |
|
+ } |
|
+ } |
|
+ else |
|
+ /* it wasn't "instant", restart counter */ |
|
+ without_fds = 0; |
|
+ } |
|
+ else |
|
+ /* got file descriptor, restart counter */ |
|
+ without_fds = 0; |
|
|
|
mcode = curl_multi_perform(multi, &still_running); |
|
} |
|
-- |
|
1.7.1 |
|
|
|
|