threads / patch / 28797

patchhttp.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

Subject: [PATCH] http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

## tl;dr

5 messages between Oct 29, 2011 and Nov 2, 2011. Diffs are folded; open one to read it.

replies: 4people: 3as markdown or json

Mika Fischer· Oct 29, 2011, 15:20 UTC · lore

Previously, when nothing could be read from the connections curl had open, git would just sleep unconditionally for 50ms. This patch changes this behavior and instead obtains the recommended timeout and the actual file descriptors from curl. This should eliminate time spent sleeping when data could actually be read/written on the socket.

Signed-off-by: Mika Fischer <mika.fischer@zoopnet.de>
---
 http.c |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)
Show changes to http.c +16 −5
diff --git a/http.c b/http.c
index a4bc770..12180f3 100644
--- a/http.c
+++ b/http.c
@@ -649,6 +649,7 @@ void run_active_slot(struct active_request_slot *slot)
 	fd_set excfds;
 	int max_fd;
 	struct timeval select_timeout;
+	long int curl_timeout;
 	int finished = 0;
 
 	slot->finished = &finished;
@@ -664,14 +665,24 @@ void run_active_slot(struct active_request_slot *slot)
 		}
 
 		if (slot->in_use && !data_received) {
-			max_fd = 0;
+			curl_multi_timeout(curlm, &curl_timeout);
+			if (curl_timeout == 0) {
+				continue;
+			} else if (curl_timeout == -1) {
+				select_timeout.tv_sec  = 0;
+				select_timeout.tv_usec = 50000;
+			} else {
+				select_timeout.tv_sec  =  curl_timeout / 1000;
+				select_timeout.tv_usec = (curl_timeout % 1000) * 1000;
+			}
+
+			max_fd = -1;
 			FD_ZERO(&readfds);
 			FD_ZERO(&writefds);
 			FD_ZERO(&excfds);
-			select_timeout.tv_sec = 0;
-			select_timeout.tv_usec = 50000;
-			select(max_fd, &readfds, &writefds,
-			       &excfds, &select_timeout);
+			curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd);
+
+			select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);
 		}
 	}
 #else
-- 
1.7.7.1.489.g1fee
Daniel Stenberg· Oct 29, 2011, 20:33 UTC · re: Mika Fischer · lore

Re: [PATCH] http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

On Sat, 29 Oct 2011, Mika Fischer wrote:
Show 5 quoted lines
> Previously, when nothing could be read from the connections curl had open, 
> git would just sleep unconditionally for 50ms. This patch changes this 
> behavior and instead obtains the recommended timeout and the actual file 
> descriptors from curl. This should eliminate time spent sleeping when data 
> could actually be read/written on the socket.

It looks fine to me, from a libcurl perspective. I only have one comment about this:

> +			curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd);
> +
> +			select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);

At times, curl_multi_fdset() might return -1 in max_fd, as when there's no internal socket around to provide to the application to wait for.

Calling select() with max_fd+1 (== 0) will then not be appreciated by all implementations of select() so that case should probably also be covered by the 50ms sleep approach...

-- 
  / daniel.haxx.se
Mika Fischer· Oct 30, 2011, 07:19 UTC · re: Daniel Stenberg · lore

Re: [PATCH] http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

On Sat, Oct 29, 2011 at 22:33, Daniel Stenberg <daniel@haxx.se> wrote:
Show 12 quoted lines
>> +                       curl_multi_fdset(curlm, &readfds, &writefds,
>> &excfds, &max_fd);
>> +
>> +                       select(max_fd+1, &readfds, &writefds, &excfds,
>> &select_timeout);
>
> At times, curl_multi_fdset() might return -1 in max_fd, as when there's no
> internal socket around to provide to the application to wait for.
>
> Calling select() with max_fd+1 (== 0) will then not be appreciated by all
> implementations of select() so that case should probably also be covered by
> the 50ms sleep approach...

Actually, the 50ms sleep was also implemented using select(0, ...) before the patch. I tried to keep the previous behavior when curl does not give us any information. I assumed that the select(0, ...) was some portable way to sleep with microsecond granularity. Is there some other way to tell select not to check any fds, or should I just call select(1, ...)?

Best,
 Mika
Mika Fischer· Nov 2, 2011, 08:21 UTC · re: Mika Fischer · lore

Re: [PATCH] http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

Show 9 quoted lines
>> Calling select() with max_fd+1 (== 0) will then not be appreciated by all
>> implementations of select() so that case should probably also be covered by
>> the 50ms sleep approach...
>
> Actually, the 50ms sleep was also implemented using select(0, ...)
> before the patch. I tried to keep the previous behavior when curl does
> not give us any information.
> I assumed that the select(0, ...) was some portable way to sleep with
> microsecond granularity.

Upon a bit of research, it seems that select(0, ...) is indeed quite commonly used. So I'd just keep it as it was unless you know of a problem it causes.

Since I'm new here, I don't really know what the next steps are for the patch, should I just wait? Or send it directly to someone?

Best,
 Mika
Junio C Hamano· Nov 2, 2011, 09:17 UTC · re: Mika Fischer · lore

Re: [PATCH] http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping

Mika Fischer <mika.fischer@zoopnet.de> writes:
> Since I'm new here, I don't really know what the next steps are for
> the patch, should I just wait? Or send it directly to someone?
Resend to the list for re-evaluation, and then we can take it from there.
Thanks.

← back to recent threads