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