Merge branch 'sz/maint-curl-multi-timeout'
authorJeff King <peff@peff.net>
Fri, 9 Nov 2012 17:50:56 +0000 (12:50 -0500)
committerJeff King <peff@peff.net>
Fri, 9 Nov 2012 17:50:56 +0000 (12:50 -0500)
Sometimes curl_multi_timeout() function suggested a wrong timeout
value when there is no file descriptors to wait on and the http
transport ended up sleeping for minutes in select(2) system call.
Detect this and reduce the wait timeout in such a case.

* sz/maint-curl-multi-timeout:
Fix potential hang in https handshake

1  2 
http.c
diff --combined http.c
index 98c0b2b362c531234ac9d02d922d23958f6d90cf,f9a9de141622549ec4338cbbfc2f430029696ebe..0a8abf3be369a18fae8e743d4cc9b5f2c2f63f03
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -631,6 -631,18 +631,18 @@@ void run_active_slot(struct active_requ
                        FD_ZERO(&excfds);
                        curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd);
  
+                       /*
+                        * It can happen that curl_multi_timeout returns a pathologically
+                        * long timeout when curl_multi_fdset returns no file descriptors
+                        * to read.  See commit message for more details.
+                        */
+                       if (max_fd < 0 &&
+                           (select_timeout.tv_sec > 0 ||
+                            select_timeout.tv_usec > 50000)) {
+                               select_timeout.tv_sec  = 0;
+                               select_timeout.tv_usec = 50000;
+                       }
                        select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);
                }
        }
@@@ -745,7 -757,8 +757,7 @@@ char *get_remote_object_url(const char 
        return strbuf_detach(&buf, NULL);
  }
  
 -int handle_curl_result(struct active_request_slot *slot,
 -                     struct slot_results *results)
 +int handle_curl_result(struct slot_results *results)
  {
        if (results->curl_result == CURLE_OK) {
                credential_approve(&http_auth);
                        return HTTP_NOAUTH;
                } else {
                        credential_fill(&http_auth);
 -                      init_curl_http_auth(slot->curl);
                        return HTTP_REAUTH;
                }
        } else {
@@@ -819,7 -833,7 +831,7 @@@ static int http_request(const char *url
  
        if (start_active_slot(slot)) {
                run_active_slot(slot);
 -              ret = handle_curl_result(slot, &results);
 +              ret = handle_curl_result(&results);
        } else {
                error("Unable to start HTTP request for %s", url);
                ret = HTTP_START_FAILED;