Re: Fix potential hang in https handshake.

2012-10-19 Thread Jeff King
On Thu, Oct 18, 2012 at 03:59:41PM -0700, Junio C Hamano wrote:

  It will sometimes happen that curl_multi_fdset() doesn't
  return any file descriptors.  In that case, it's recommended
  that the application sleep for a short time before running
  curl_multi_perform() again.
 
  http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
 
  Signed-off-by: Stefan Zager sza...@google.com
  ---
 
 Thanks.  Would it be a better idea to patch up in problematic
 case, instead of making this logic too deeply nested, like this
 instead, I have to wonder...
 
 
   ... all the existing code above unchanged ...
   curl_multi_fdset(..., max_fd);
 + if (max_fd  0) {
 + /* nothing actionable??? */
 + select_timeout.tv_sec = 0;
 + select_timeout.tv_usec = 5;
 + }
 
   select(max_fd+1, ..., select_timeout);

But wouldn't that override a potentially shorter timeout that curl gave
us via curl_multi_timeout, making us unnecessarily slow to hand control
back to curl?

The current logic is:

  - if curl says there is something to do now (timeout == 0), do it
immediately

  - if curl gives us a timeout, use it with select

  - otherwise, feed 50ms to selection

It should not matter what we get from curl_multi_fdset. If there are
fds, great, we will feed them to select with the timeout, and we may
break out early if there is work to do. If not, then we are already
doing this wait.

IOW, it seems like we are _already_ following the advice referenced in
curl's manpage. Is there some case I am missing? Confused...

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Shawn Pearce
On Fri, Oct 19, 2012 at 3:36 AM, Jeff King p...@peff.net wrote:
 On Thu, Oct 18, 2012 at 03:59:41PM -0700, Junio C Hamano wrote:

  It will sometimes happen that curl_multi_fdset() doesn't
  return any file descriptors.  In that case, it's recommended
  that the application sleep for a short time before running
  curl_multi_perform() again.
 
  http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
 
  Signed-off-by: Stefan Zager sza...@google.com
  ---

 Thanks.  Would it be a better idea to patch up in problematic
 case, instead of making this logic too deeply nested, like this
 instead, I have to wonder...


   ... all the existing code above unchanged ...
   curl_multi_fdset(..., max_fd);
 + if (max_fd  0) {
 + /* nothing actionable??? */
 + select_timeout.tv_sec = 0;
 + select_timeout.tv_usec = 5;
 + }

   select(max_fd+1, ..., select_timeout);

 But wouldn't that override a potentially shorter timeout that curl gave
 us via curl_multi_timeout, making us unnecessarily slow to hand control
 back to curl?

 The current logic is:

   - if curl says there is something to do now (timeout == 0), do it
 immediately

   - if curl gives us a timeout, use it with select

   - otherwise, feed 50ms to selection

 It should not matter what we get from curl_multi_fdset. If there are
 fds, great, we will feed them to select with the timeout, and we may
 break out early if there is work to do. If not, then we are already
 doing this wait.

 IOW, it seems like we are _already_ following the advice referenced in
 curl's manpage. Is there some case I am missing? Confused...

The issue with the current code is sometimes when libcurl is opening a
CONNECT style connection through an HTTP proxy it returns a crazy high
timeout (240 seconds) and no fds. In this case Git waits forever.
Stefan observed that using a timeout of 50 ms in this situation to
poll libcurl is better, as it figures out a lot more quickly that it
is connected to the proxy and can issue the request.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Junio C Hamano
Stefan Zager sza...@google.com writes:

 On Oct 19, 2012 7:11 AM, Shawn Pearce spea...@spearce.org wrote:

 The issue with the current code is sometimes when libcurl is opening a
 CONNECT style connection through an HTTP proxy it returns a crazy high
 timeout (240 seconds) and no fds. In this case Git waits forever.
 Stefan observed that using a timeout of 50 ms in this situation to
 poll libcurl is better, as it figures out a lot more quickly that it
 is connected to the proxy and can issue the request.

 Correct.  Anecdotally, the zero-file-descriptor situation happens only once
 per process invocation, so the risk of passing a too-long timeout to
 select() is small.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Daniel Stenberg

On Fri, 19 Oct 2012, Shawn Pearce wrote:

The issue with the current code is sometimes when libcurl is opening a 
CONNECT style connection through an HTTP proxy it returns a crazy high 
timeout (240 seconds) and no fds. In this case Git waits forever.


Is this repeatable with a recent libcurl? It certainly sounds like a bug to 
me, and I might be interested in giving a try at tracking it down...


--

 / daniel.haxx.se
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Jeff King
On Fri, Oct 19, 2012 at 07:10:46AM -0700, Shawn O. Pearce wrote:

  IOW, it seems like we are _already_ following the advice referenced in
  curl's manpage. Is there some case I am missing? Confused...
 
 The issue with the current code is sometimes when libcurl is opening a
 CONNECT style connection through an HTTP proxy it returns a crazy high
 timeout (240 seconds) and no fds. In this case Git waits forever.
 Stefan observed that using a timeout of 50 ms in this situation to
 poll libcurl is better, as it figures out a lot more quickly that it
 is connected to the proxy and can issue the request.

Ah. That sounds like a bug in curl to me. But either way, if we want to
work around it, wouldn't the right thing be to override curl's timeout
in that instance? Like:

diff --git a/http.c b/http.c
index df9bb71..cd07cdf 100644
--- a/http.c
+++ b/http.c
@@ -631,6 +631,19 @@ void run_active_slot(struct active_request_slot *slot)
FD_ZERO(excfds);
curl_multi_fdset(curlm, readfds, writefds, excfds, 
max_fd);
 
+   /*
+* Sometimes curl will give a really long timeout for a
+* CONNECT when there are no fds to read, but we can
+* get better results by running curl_multi_perform
+* more frequently.
+*/
+   if (maxfd  0 
+   (select_timeout.tv_sec  0 ||
+select_timeout.tv_usec  5)) {
+   select_timeout.tv_sec = 0;
+   select_timeout.tv_usec = 5;
+   }
+
select(max_fd+1, readfds, writefds, excfds, 
select_timeout);
}
}

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Stefan Zager
On Fri, Oct 19, 2012 at 1:27 PM, Jeff King p...@peff.net wrote:

 On Fri, Oct 19, 2012 at 07:10:46AM -0700, Shawn O. Pearce wrote:

   IOW, it seems like we are _already_ following the advice referenced in
   curl's manpage. Is there some case I am missing? Confused...
 
  The issue with the current code is sometimes when libcurl is opening a
  CONNECT style connection through an HTTP proxy it returns a crazy high
  timeout (240 seconds) and no fds. In this case Git waits forever.
  Stefan observed that using a timeout of 50 ms in this situation to
  poll libcurl is better, as it figures out a lot more quickly that it
  is connected to the proxy and can issue the request.

 Ah. That sounds like a bug in curl to me. But either way, if we want to
 work around it, wouldn't the right thing be to override curl's timeout
 in that instance? Like:

 diff --git a/http.c b/http.c
 index df9bb71..cd07cdf 100644
 --- a/http.c
 +++ b/http.c
 @@ -631,6 +631,19 @@ void run_active_slot(struct active_request_slot *slot)
 FD_ZERO(excfds);
 curl_multi_fdset(curlm, readfds, writefds, excfds, 
 max_fd);

 +   /*
 +* Sometimes curl will give a really long timeout for 
 a
 +* CONNECT when there are no fds to read, but we can
 +* get better results by running curl_multi_perform
 +* more frequently.
 +*/
 +   if (maxfd  0 
 +   (select_timeout.tv_sec  0 ||
 +select_timeout.tv_usec  5)) {
 +   select_timeout.tv_sec = 0;
 +   select_timeout.tv_usec = 5;
 +   }
 +
 select(max_fd+1, readfds, writefds, excfds, 
 select_timeout);
 }
 }

 -Peff

I have no objection to this; any one else?

Stefan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-19 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Fri, Oct 19, 2012 at 07:10:46AM -0700, Shawn O. Pearce wrote:

  IOW, it seems like we are _already_ following the advice referenced in
  curl's manpage. Is there some case I am missing? Confused...
 
 The issue with the current code is sometimes when libcurl is opening a
 CONNECT style connection through an HTTP proxy it returns a crazy high
 timeout (240 seconds) and no fds. In this case Git waits forever.
 Stefan observed that using a timeout of 50 ms in this situation to
 poll libcurl is better, as it figures out a lot more quickly that it
 is connected to the proxy and can issue the request.

 Ah. That sounds like a bug in curl to me. But either way, if we want to
 work around it, wouldn't the right thing be to override curl's timeout
 in that instance? Like:

Yeah, that sounds like a more targetted workaround (read: better).


 diff --git a/http.c b/http.c
 index df9bb71..cd07cdf 100644
 --- a/http.c
 +++ b/http.c
 @@ -631,6 +631,19 @@ void run_active_slot(struct active_request_slot *slot)
   FD_ZERO(excfds);
   curl_multi_fdset(curlm, readfds, writefds, excfds, 
 max_fd);
  
 + /*
 +  * Sometimes curl will give a really long timeout for a
 +  * CONNECT when there are no fds to read, but we can
 +  * get better results by running curl_multi_perform
 +  * more frequently.
 +  */
 + if (maxfd  0 
 + (select_timeout.tv_sec  0 ||
 +  select_timeout.tv_usec  5)) {
 + select_timeout.tv_sec = 0;
 + select_timeout.tv_usec = 5;
 + }
 +
   select(max_fd+1, readfds, writefds, excfds, 
 select_timeout);
   }
   }

 -Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Fix potential hang in https handshake (v3)

2012-10-19 Thread szager
From 32e06128dbc97ceb0d060c88ec8db204fa51be5c Mon Sep 17 00:00:00 2001
From: Stefan Zager sza...@google.com
Date: Thu, 18 Oct 2012 16:23:53 -0700
Subject: [PATCH] Fix potential hang in https handshake.

It has been observed that curl_multi_timeout may return a very long
timeout value (e.g., 294 seconds and some usec) just before
curl_multi_fdset returns no file descriptors for reading.  The
upshot is that select() will hang for a long time -- long enough for
an https handshake to be dropped.  The observed behavior is that
the git command will hang at the terminal and never transfer any
data.

This patch is a workaround for a probable bug in libcurl.  The bug
only seems to manifest around a very specific set of circumstances:

- curl version (from curl/curlver.h):

 #define LIBCURL_VERSION_NUM 0x071307

- git-remote-https running on an ubuntu-lucid VM.
- Connecting through squid proxy running on another VM.

Interestingly, the problem doesn't manifest if a host connects
through squid proxy running on localhost; only if the proxy is on
a separate VM (not sure if the squid host needs to be on a separate
physical machine).  That would seem to suggest that this issue
is timing-sensitive.

This patch is more or less in line with a recommendation in the
curl docs about how to behave when curl_multi_fdset doesn't return
and file descriptors:

http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

Signed-off-by: Stefan Zager sza...@google.com
---
 http.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/http.c b/http.c
index df9bb71..51eef02 100644
--- a/http.c
+++ b/http.c
@@ -631,6 +631,17 @@ void run_active_slot(struct active_request_slot *slot)
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  5) {
+   select_timeout.tv_sec  = 0;
+   select_timeout.tv_usec = 5;
+   }
+
select(max_fd+1, readfds, writefds, excfds, 
select_timeout);
}
}
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake (v3)

2012-10-19 Thread Jeff King
On Fri, Oct 19, 2012 at 02:04:20PM -0700, sza...@google.com wrote:

 From 32e06128dbc97ceb0d060c88ec8db204fa51be5c Mon Sep 17 00:00:00 2001
 From: Stefan Zager sza...@google.com
 Date: Thu, 18 Oct 2012 16:23:53 -0700

Drop these lines.

 Subject: [PATCH] Fix potential hang in https handshake.

And make this one your actual email subject.

 It has been observed that curl_multi_timeout may return a very long
 timeout value (e.g., 294 seconds and some usec) just before
 curl_multi_fdset returns no file descriptors for reading.  The
 upshot is that select() will hang for a long time -- long enough for
 an https handshake to be dropped.  The observed behavior is that
 the git command will hang at the terminal and never transfer any
 data.
 
 This patch is a workaround for a probable bug in libcurl.  The bug
 only seems to manifest around a very specific set of circumstances:
 
 - curl version (from curl/curlver.h):
 
  #define LIBCURL_VERSION_NUM 0x071307
 
 - git-remote-https running on an ubuntu-lucid VM.
 - Connecting through squid proxy running on another VM.
 
 Interestingly, the problem doesn't manifest if a host connects
 through squid proxy running on localhost; only if the proxy is on
 a separate VM (not sure if the squid host needs to be on a separate
 physical machine).  That would seem to suggest that this issue
 is timing-sensitive.

Thanks, that explanation makes much more sense.

 diff --git a/http.c b/http.c
 index df9bb71..51eef02 100644
 --- a/http.c
 +++ b/http.c
 @@ -631,6 +631,17 @@ void run_active_slot(struct active_request_slot *slot)
   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.
 +  */

Minor nit, but our multi-line comment style is:

  /*
   * blah blah blah
   */

 + if (max_fd  0 
 + select_timeout.tv_sec  0 ||
 + select_timeout.tv_usec  5) {
 + select_timeout.tv_sec  = 0;
 + select_timeout.tv_usec = 5;
 + }

Should there be parentheses separating the || bit from the ?

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake (v3)

2012-10-19 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 +if (max_fd  0 
 +select_timeout.tv_sec  0 ||
 +select_timeout.tv_usec  5) {
 +select_timeout.tv_sec  = 0;
 +select_timeout.tv_usec = 5;
 +}

 Should there be parentheses separating the || bit from the ?

Yeah, I think there should be.  Thanks for sharp eyes.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Fix potential hang in https handshake.

2012-10-19 Thread szager
It has been observed that curl_multi_timeout may return a very long
timeout value (e.g., 294 seconds and some usec) just before
curl_multi_fdset returns no file descriptors for reading.  The
upshot is that select() will hang for a long time -- long enough for
an https handshake to be dropped.  The observed behavior is that
the git command will hang at the terminal and never transfer any
data.

This patch is a workaround for a probable bug in libcurl.  The bug
only seems to manifest around a very specific set of circumstances:

- curl version (from curl/curlver.h):

 #define LIBCURL_VERSION_NUM 0x071307

- git-remote-https running on an ubuntu-lucid VM.
- Connecting through squid proxy running on another VM.

Interestingly, the problem doesn't manifest if a host connects
through squid proxy running on localhost; only if the proxy is on
a separate VM (not sure if the squid host needs to be on a separate
physical machine).  That would seem to suggest that this issue
is timing-sensitive.

This patch is more or less in line with a recommendation in the
curl docs about how to behave when curl_multi_fdset doesn't return
and file descriptors:

http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

Signed-off-by: Stefan Zager sza...@google.com
---
 http.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/http.c b/http.c
index df9bb71..b7e7ab4 100644
--- a/http.c
+++ b/http.c
@@ -631,6 +631,18 @@ void run_active_slot(struct active_request_slot *slot)
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  5)) {
+   select_timeout.tv_sec  = 0;
+select_timeout.tv_usec = 5;
+   }
+
select(max_fd+1, readfds, writefds, excfds, 
select_timeout);
}
}
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Fix potential hang in https handshake.

2012-10-19 Thread Junio C Hamano
Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Fix potential hang in https handshake.

2012-10-18 Thread szager
From 700b8075c578941c8f951711825c390ac68b190f Mon Sep 17 00:00:00 2001
From: Stefan Zager sza...@google.com
Date: Thu, 18 Oct 2012 14:03:59 -0700
Subject: [PATCH] Fix potential hang in https handshake.

It will sometimes happen that curl_multi_fdset() doesn't
return any file descriptors.  In that case, it's recommended
that the application sleep for a short time before running
curl_multi_perform() again.

http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

Signed-off-by: Stefan Zager sza...@google.com
---
 http.c |   40 ++--
 1 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/http.c b/http.c
index df9bb71..a6f66c0 100644
--- a/http.c
+++ b/http.c
@@ -602,35 +602,47 @@ void run_active_slot(struct active_request_slot *slot)
int max_fd;
struct timeval select_timeout;
int finished = 0;
+   long curl_timeout;
 
slot-finished = finished;
while (!finished) {
step_active_slots();
 
if (slot-in_use) {
+   max_fd = -1;
+   FD_ZERO(readfds);
+   FD_ZERO(writefds);
+   FD_ZERO(excfds);
+   curl_multi_fdset(curlm, readfds, writefds, excfds, 
max_fd);
+
 #if LIBCURL_VERSION_NUM = 0x070f04
-   long curl_timeout;
-   curl_multi_timeout(curlm, curl_timeout);
-   if (curl_timeout == 0) {
-   continue;
-   } else if (curl_timeout == -1) {
+   /* It will sometimes happen that curl_multi_fdset() 
doesn't
+  return any file descriptors.  In that case, it's 
recommended
+  that the application sleep for a short time before 
running
+  curl_multi_perform() again.
+
+  http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
+   */
+   if (max_fd == -1) {
select_timeout.tv_sec  = 0;
select_timeout.tv_usec = 5;
} else {
-   select_timeout.tv_sec  =  curl_timeout / 1000;
-   select_timeout.tv_usec = (curl_timeout % 1000) 
* 1000;
+   curl_timeout = 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 = 5;
+   } 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 = 5;
 #endif
-
-   max_fd = -1;
-   FD_ZERO(readfds);
-   FD_ZERO(writefds);
-   FD_ZERO(excfds);
-   curl_multi_fdset(curlm, readfds, writefds, excfds, 
max_fd);
-
select(max_fd+1, readfds, writefds, excfds, 
select_timeout);
}
}
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake.

2012-10-18 Thread Junio C Hamano
sza...@google.com writes:

 From 700b8075c578941c8f951711825c390ac68b190f Mon Sep 17 00:00:00 2001
 From: Stefan Zager sza...@google.com
 Date: Thu, 18 Oct 2012 14:03:59 -0700
 Subject: [PATCH] Fix potential hang in https handshake.

 It will sometimes happen that curl_multi_fdset() doesn't
 return any file descriptors.  In that case, it's recommended
 that the application sleep for a short time before running
 curl_multi_perform() again.

 http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

 Signed-off-by: Stefan Zager sza...@google.com
 ---

Thanks.  Would it be a better idea to patch up in problematic
case, instead of making this logic too deeply nested, like this
instead, I have to wonder...


... all the existing code above unchanged ...
curl_multi_fdset(..., max_fd);
+   if (max_fd  0) {
+   /* nothing actionable??? */
+   select_timeout.tv_sec = 0;
+   select_timeout.tv_usec = 5;
+   }

select(max_fd+1, ..., select_timeout);



  http.c |   40 ++--
  1 files changed, 26 insertions(+), 14 deletions(-)

 diff --git a/http.c b/http.c
 index df9bb71..a6f66c0 100644
 --- a/http.c
 +++ b/http.c
 @@ -602,35 +602,47 @@ void run_active_slot(struct active_request_slot *slot)
   int max_fd;
   struct timeval select_timeout;
   int finished = 0;
 + long curl_timeout;
  
   slot-finished = finished;
   while (!finished) {
   step_active_slots();
  
   if (slot-in_use) {
 + max_fd = -1;
 + FD_ZERO(readfds);
 + FD_ZERO(writefds);
 + FD_ZERO(excfds);
 + curl_multi_fdset(curlm, readfds, writefds, excfds, 
 max_fd);
 +
  #if LIBCURL_VERSION_NUM = 0x070f04
 - long curl_timeout;
 - curl_multi_timeout(curlm, curl_timeout);
 - if (curl_timeout == 0) {
 - continue;
 - } else if (curl_timeout == -1) {
 + /* It will sometimes happen that curl_multi_fdset() 
 doesn't
 +return any file descriptors.  In that case, it's 
 recommended
 +that the application sleep for a short time before 
 running
 +curl_multi_perform() again.
 +
 +http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
 + */
 + if (max_fd == -1) {
   select_timeout.tv_sec  = 0;
   select_timeout.tv_usec = 5;
   } else {
 - select_timeout.tv_sec  =  curl_timeout / 1000;
 - select_timeout.tv_usec = (curl_timeout % 1000) 
 * 1000;
 + curl_timeout = 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 = 5;
 + } 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 = 5;
  #endif
 -
 - max_fd = -1;
 - FD_ZERO(readfds);
 - FD_ZERO(writefds);
 - FD_ZERO(excfds);
 - curl_multi_fdset(curlm, readfds, writefds, excfds, 
 max_fd);
 -
   select(max_fd+1, readfds, writefds, excfds, 
 select_timeout);
   }
   }
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Fix potential hang in https handshake (v2).

2012-10-18 Thread szager
From aa77ab3dd5b98a5786ac158528f45355fc0ddbc3 Mon Sep 17 00:00:00 2001
From: Stefan Zager sza...@google.com
Date: Thu, 18 Oct 2012 16:23:53 -0700
Subject: [PATCH] Fix potential hang in https handshake.

It will sometimes happen that curl_multi_fdset() doesn't
return any file descriptors.  In that case, it's recommended
that the application sleep for a short time before running
curl_multi_perform() again.

http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

Signed-off-by: Stefan Zager sza...@google.com
---
 http.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/http.c b/http.c
index df9bb71..e8aba7f 100644
--- a/http.c
+++ b/http.c
@@ -630,6 +630,10 @@ void run_active_slot(struct active_request_slot *slot)
FD_ZERO(writefds);
FD_ZERO(excfds);
curl_multi_fdset(curlm, readfds, writefds, excfds, 
max_fd);
+   if (max_fd  0) {
+   select_timeout.tv_sec  = 0;
+   select_timeout.tv_usec = 5;
+   }
 
select(max_fd+1, readfds, writefds, excfds, 
select_timeout);
}
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake (v2).

2012-10-18 Thread Junio C Hamano
sza...@google.com writes:

 From aa77ab3dd5b98a5786ac158528f45355fc0ddbc3 Mon Sep 17 00:00:00 2001
 From: Stefan Zager sza...@google.com
 Date: Thu, 18 Oct 2012 16:23:53 -0700
 Subject: [PATCH] Fix potential hang in https handshake.

Please don't do the above (as usual ;-)

 It will sometimes happen that curl_multi_fdset() doesn't
 return any file descriptors.  In that case, it's recommended
 that the application sleep for a short time before running
 curl_multi_perform() again.

 http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

 Signed-off-by: Stefan Zager sza...@google.com
 ---

The above sounds like the code is doing something against a
recommended practice, but is there a user-visible symptom due to
this?

We end up calling select() without any bit set in fds, so it would
become micro-sleep of select_timeout in such a case, but as far as I
can see, the existing code either

 * does not select() and keeps polling step_active_slots() without
   delay, when curl_timeout gives a 0 return value; or

 * sets 50ms timeout or whatever negative value derived from
   curl_timeout when the returned value is not 0 nor -1.

Is the symptom that select(), when given a negative timeout and no
fd to wake it, sleeps forever (or lng time, taking that negative
value as if it is a large unsigned long) or something?

Thanks.

  http.c |4 
  1 files changed, 4 insertions(+), 0 deletions(-)

 diff --git a/http.c b/http.c
 index df9bb71..e8aba7f 100644
 --- a/http.c
 +++ b/http.c
 @@ -630,6 +630,10 @@ void run_active_slot(struct active_request_slot *slot)
   FD_ZERO(writefds);
   FD_ZERO(excfds);
   curl_multi_fdset(curlm, readfds, writefds, excfds, 
 max_fd);
 + if (max_fd  0) {
 + select_timeout.tv_sec  = 0;
 + select_timeout.tv_usec = 5;
 + }
  
   select(max_fd+1, readfds, writefds, excfds, 
 select_timeout);
   }
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fix potential hang in https handshake (v2).

2012-10-18 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 We end up calling select() without any bit set in fds, so it would
 become micro-sleep of select_timeout in such a case, but as far as I
 can see, the existing code either

  * does not select() and keeps polling step_active_slots() without
delay, when curl_timeout gives a 0 return value; or

  * sets 50ms timeout or whatever negative value derived from
curl_timeout when the returned value is not 0 nor -1.

 Is the symptom that select(), when given a negative timeout and no
 fd to wake it, sleeps forever (or lng time, taking that negative
 value as if it is a large unsigned long) or something?

Addendum.

What I am trying to get at are (1) three line description I can put
in the release notes for this fix when it is merged to the
maintenance track, and (2) a feel of how often this happens and how
bad the damage is.

The latter helps us judge if this do the normal thing, but if in a
rare case where we do not find any fds, patch it up to proceed is a
better approach over your original.

Thanks.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html