From 6f9dd67ffea3e86276a73e522ce1186a99bbe65d Mon Sep 17 00:00:00 2001 From: Mika Fischer Date: Fri, 4 Nov 2011 15:19:25 +0100 Subject: http.c: Use curl_multi_fdset to select on curl fds instead of just sleeping Instead of sleeping unconditionally for a 50ms, when no data can be read from the http connection(s), use curl_multi_fdset() to obtain the actual file descriptors of the open connections and use them in the select call. This way, the 50ms sleep is interrupted when new data arrives. Signed-off-by: Mika Fischer Helped-by: Daniel Stenberg Signed-off-by: Junio C Hamano diff --git a/http.c b/http.c index b2ae8de..a815f62 100644 --- a/http.c +++ b/http.c @@ -651,14 +651,14 @@ void run_active_slot(struct active_request_slot *slot) } if (slot->in_use && !data_received) { - max_fd = 0; + max_fd = -1; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&excfds); + curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd); select_timeout.tv_sec = 0; select_timeout.tv_usec = 50000; - select(max_fd, &readfds, &writefds, - &excfds, &select_timeout); + select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); } } #else -- cgit v0.10.2-6-g49f6 From eb56c82163487fe07ba04f2b365a557282cbd766 Mon Sep 17 00:00:00 2001 From: Mika Fischer Date: Fri, 4 Nov 2011 15:19:26 +0100 Subject: http.c: Use timeout suggested by curl instead of fixed 50ms timeout Recent versions of curl can suggest a period of time the library user should sleep and try again, when curl is blocked on reading or writing (or connecting). Use this timeout instead of always sleeping for 50ms. Signed-off-by: Mika Fischer Helped-by: Daniel Stenberg Signed-off-by: Junio C Hamano diff --git a/http.c b/http.c index a815f62..924be52 100644 --- a/http.c +++ b/http.c @@ -651,13 +651,29 @@ void run_active_slot(struct active_request_slot *slot) } if (slot->in_use && !data_received) { +#if LIBCURL_VERSION_NUM >= 0x070f04 + long curl_timeout; + 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; + } +#else + select_timeout.tv_sec = 0; + select_timeout.tv_usec = 50000; +#endif + max_fd = -1; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&excfds); curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd); - select_timeout.tv_sec = 0; - select_timeout.tv_usec = 50000; + select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); } } -- cgit v0.10.2-6-g49f6 From df26c471278f13ca6ad96b12a533ef4172323c13 Mon Sep 17 00:00:00 2001 From: Mika Fischer Date: Fri, 4 Nov 2011 15:19:27 +0100 Subject: http.c: Rely on select instead of tracking whether data was received Since now select is used with the file descriptors of the http connections, tracking whether data was received recently (and trying to read more in that case) is no longer necessary. Instead, always call select and rely on it to return as soon as new data can be read. Signed-off-by: Mika Fischer Helped-by: Jeff King Signed-off-by: Junio C Hamano diff --git a/http.c b/http.c index 924be52..2083efe 100644 --- a/http.c +++ b/http.c @@ -4,7 +4,6 @@ #include "run-command.h" #include "url.h" -int data_received; int active_requests; int http_is_verbose; size_t http_post_buffer = 16 * LARGE_PACKET_MAX; @@ -98,13 +97,11 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_) struct strbuf *buffer = buffer_; strbuf_add(buffer, ptr, size); - data_received++; return size; } size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf) { - data_received++; return eltsize * nmemb; } @@ -629,8 +626,6 @@ void step_active_slots(void) void run_active_slot(struct active_request_slot *slot) { #ifdef USE_CURL_MULTI - long last_pos = 0; - long current_pos; fd_set readfds; fd_set writefds; fd_set excfds; @@ -640,17 +635,9 @@ void run_active_slot(struct active_request_slot *slot) slot->finished = &finished; while (!finished) { - data_received = 0; step_active_slots(); - if (!data_received && slot->local != NULL) { - current_pos = ftell(slot->local); - if (current_pos > last_pos) - data_received++; - last_pos = current_pos; - } - - if (slot->in_use && !data_received) { + if (slot->in_use) { #if LIBCURL_VERSION_NUM >= 0x070f04 long curl_timeout; curl_multi_timeout(curlm, &curl_timeout); @@ -1208,7 +1195,6 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb, git_SHA1_Update(&freq->c, expn, sizeof(expn) - freq->stream.avail_out); } while (freq->stream.avail_in && freq->zret == Z_OK); - data_received++; return size; } diff --git a/http.h b/http.h index 19b7134..d0089d1 100644 --- a/http.h +++ b/http.h @@ -89,7 +89,6 @@ extern void step_active_slots(void); extern void http_init(struct remote *remote); extern void http_cleanup(void); -extern int data_received; extern int active_requests; extern int http_is_verbose; extern size_t http_post_buffer; -- cgit v0.10.2-6-g49f6 From 093c44a3600323c3ca7a8d28a0d2ba2bc145dd47 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Nov 2011 13:53:33 -0400 Subject: http: drop "local" member from request struct This is a FILE pointer in the case that we are sending our output to a file. We originally used it to run ftell() to determine whether data had been written to our file during our last call to curl. However, as of the last patch, we no longer care about that flag anymore. All uses of this struct member are now just book-keeping that can go away. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano diff --git a/http.c b/http.c index 2083efe..59592db 100644 --- a/http.c +++ b/http.c @@ -523,7 +523,6 @@ struct active_request_slot *get_active_slot(void) active_requests++; slot->in_use = 1; - slot->local = NULL; slot->results = NULL; slot->finished = NULL; slot->callback_data = NULL; @@ -814,7 +813,6 @@ static int http_request(const char *url, void *result, int target, int options) headers = curl_slist_append(headers, buf.buf); strbuf_reset(&buf); } - slot->local = result; } else curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); @@ -856,7 +854,6 @@ static int http_request(const char *url, void *result, int target, int options) ret = HTTP_START_FAILED; } - slot->local = NULL; curl_slist_free_all(headers); strbuf_release(&buf); @@ -1046,7 +1043,6 @@ void release_http_pack_request(struct http_pack_request *preq) if (preq->packfile != NULL) { fclose(preq->packfile); preq->packfile = NULL; - preq->slot->local = NULL; } if (preq->range_header != NULL) { curl_slist_free_all(preq->range_header); @@ -1068,7 +1064,6 @@ int finish_http_pack_request(struct http_pack_request *preq) fclose(preq->packfile); preq->packfile = NULL; - preq->slot->local = NULL; lst = preq->lst; while (*lst != p) @@ -1138,7 +1133,6 @@ struct http_pack_request *new_http_pack_request( } preq->slot = get_active_slot(); - preq->slot->local = preq->packfile; curl_easy_setopt(preq->slot->curl, CURLOPT_FILE, preq->packfile); curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url); diff --git a/http.h b/http.h index d0089d1..368bc0e 100644 --- a/http.h +++ b/http.h @@ -49,7 +49,6 @@ struct slot_results { struct active_request_slot { CURL *curl; - FILE *local; int in_use; CURLcode curl_result; long http_code; -- cgit v0.10.2-6-g49f6