cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] timeout in ms

From: Michael Wallner <mike_at_iworks.at>
Date: Tue, 30 Jan 2007 10:45:58 +0100

Hi,

attached is a patch against current CVS, which is supposed to add timeout
support in milliseconds (CURLOPT_TIMEOUT_MS, CURLOPT_CONNECTTIMEOUT_MS).

AFAICT, there are three issues left:
        - SIGALRM, alarm() accepts seconds only
        - CONNECT, I lowered the timeout to 10ms
        - ftp_response_timeout, didn't touch this

Regards,

-- 
Michael

? compile
? timeout_ms.diff.txt
Index: include/curl/curl.h
===================================================================
RCS file: /cvsroot/curl/curl/include/curl/curl.h,v
retrieving revision 1.313
diff -u -p -d -r1.313 curl.h
--- include/curl/curl.h 8 Jan 2007 11:24:11 -0000 1.313
+++ include/curl/curl.h 30 Jan 2007 09:38:38 -0000
@@ -1054,6 +1054,10 @@ typedef enum {
   /* Send CCC (Clear Command Channel) after authentication */
   CINIT(FTP_SSL_CCC, LONG, 154),
 
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CINIT(TIMEOUT_MS, LONG, 155),
+ CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
Index: lib/connect.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/connect.c,v
retrieving revision 1.158
diff -u -p -d -r1.158 connect.c
--- lib/connect.c 22 Dec 2006 13:30:54 -0000 1.158
+++ lib/connect.c 30 Jan 2007 09:38:40 -0000
@@ -558,15 +558,15 @@ CURLcode Curl_is_connected(struct connec
   /* subtract the most strict timeout of the ones */
   if(data->set.timeout && data->set.connecttimeout) {
     if (data->set.timeout < data->set.connecttimeout)
- allow_total = allow = data->set.timeout*1000;
+ allow_total = allow = data->set.timeout;
     else
- allow = data->set.connecttimeout*1000;
+ allow = data->set.connecttimeout;
   }
   else if(data->set.timeout) {
- allow_total = allow = data->set.timeout*1000;
+ allow_total = allow = data->set.timeout;
   }
   else if(data->set.connecttimeout) {
- allow = data->set.connecttimeout*1000;
+ allow = data->set.connecttimeout;
   }
 
   if(has_passed > allow ) {
@@ -826,14 +826,14 @@ CURLcode Curl_connecthost(struct connect
     /* get the most strict timeout of the ones converted to milliseconds */
     if(data->set.timeout && data->set.connecttimeout) {
       if (data->set.timeout < data->set.connecttimeout)
- timeout_ms = data->set.timeout*1000;
+ timeout_ms = data->set.timeout;
       else
- timeout_ms = data->set.connecttimeout*1000;
+ timeout_ms = data->set.connecttimeout;
     }
     else if(data->set.timeout)
- timeout_ms = data->set.timeout*1000;
+ timeout_ms = data->set.timeout;
     else
- timeout_ms = data->set.connecttimeout*1000;
+ timeout_ms = data->set.connecttimeout;
 
     /* subtract the passed time */
     timeout_ms -= has_passed;
Index: lib/ftp.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ftp.c,v
retrieving revision 1.391
diff -u -p -d -r1.391 ftp.c
--- lib/ftp.c 24 Jan 2007 19:09:12 -0000 1.391
+++ lib/ftp.c 30 Jan 2007 09:38:50 -0000
@@ -184,7 +184,7 @@ static CURLcode AllowServerConnect(struc
   struct SessionHandle *data = conn->data;
   curl_socket_t sock = conn->sock[SECONDARYSOCKET];
   struct timeval now = Curl_tvnow();
- long timespent = Curl_tvdiff(Curl_tvnow(), now)/1000;
+ long timespent = Curl_tvdiff(Curl_tvnow(), now);
   long timeout = data->set.connecttimeout?data->set.connecttimeout:
     (data->set.timeout?data->set.timeout: 0);
 
@@ -198,7 +198,7 @@ static CURLcode AllowServerConnect(struc
 
   /* We allow the server 60 seconds to connect to us, or a custom timeout.
      Note the typecast here. */
- timeout_ms = (timeout?(int)timeout:60) * 1000;
+ timeout_ms = (timeout?(int)timeout:60000);
 
   switch (Curl_select(sock, CURL_SOCKET_BAD, timeout_ms)) {
   case -1: /* error */
Index: lib/gtls.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/gtls.c,v
retrieving revision 1.18
diff -u -p -d -r1.18 gtls.c
--- lib/gtls.c 5 Jan 2007 23:11:16 -0000 1.18
+++ lib/gtls.c 30 Jan 2007 09:38:52 -0000
@@ -144,12 +144,12 @@ static CURLcode handshake(struct connect
       long has_passed;
 
       if(duringconnect && data->set.connecttimeout)
- timeout_ms = data->set.connecttimeout*1000;
+ timeout_ms = data->set.connecttimeout;
 
       if(data->set.timeout) {
         /* get the strictest timeout of the ones converted to milliseconds */
- if((data->set.timeout*1000) < timeout_ms)
- timeout_ms = data->set.timeout*1000;
+ if(data->set.timeout) < timeout_ms)
+ timeout_ms = data->set.timeout;
       }
 
       /* Evaluate in milliseconds how much time that has passed */
Index: lib/hostares.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/hostares.c,v
retrieving revision 1.25
diff -u -p -d -r1.25 hostares.c
--- lib/hostares.c 17 Oct 2006 08:06:27 -0000 1.25
+++ lib/hostares.c 30 Jan 2007 09:38:53 -0000
@@ -183,7 +183,7 @@ CURLcode Curl_wait_for_resolv(struct con
 {
   CURLcode rc=CURLE_OK;
   struct SessionHandle *data = conn->data;
- long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
+ long timeout;
 
   /* now, see if there's a connect timeout or a regular timeout to
      use instead of the default one */
@@ -191,14 +191,8 @@ CURLcode Curl_wait_for_resolv(struct con
     timeout = conn->data->set.connecttimeout;
   else if(conn->data->set.timeout)
     timeout = conn->data->set.timeout;
-
- /* We convert the number of seconds into number of milliseconds here: */
- if(timeout < 2147483)
- /* maximum amount of seconds that can be multiplied with 1000 and
- still fit within 31 bits */
- timeout *= 1000;
   else
- timeout = 0x7fffffff; /* ridiculous amount of time anyway */
+ timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
 
   /* Wait for the name resolve query to complete. */
   while (1) {
Index: lib/hostthre.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/hostthre.c,v
retrieving revision 1.43
diff -u -p -d -r1.43 hostthre.c
--- lib/hostthre.c 17 Oct 2006 20:34:11 -0000 1.43
+++ lib/hostthre.c 30 Jan 2007 09:38:55 -0000
@@ -600,7 +600,7 @@ CURLcode Curl_wait_for_resolv(struct con
   ticks = GetTickCount();
 
   /* wait for the thread to resolve the name */
- status = WaitForSingleObject(td->event_resolved, 1000UL*timeout);
+ status = WaitForSingleObject(td->event_resolved, timeout);
 
   /* mark that we are now done waiting */
   ReleaseMutex(td->mutex_waiting);
Index: lib/http.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/http.c,v
retrieving revision 1.310
diff -u -p -d -r1.310 http.c
--- lib/http.c 29 Jan 2007 09:26:37 -0000 1.310
+++ lib/http.c 30 Jan 2007 09:39:01 -0000
@@ -1121,7 +1121,7 @@ CURLcode Curl_proxyCONNECT(struct connec
   ssize_t gotbytes;
   char *ptr;
   long timeout =
- data->set.timeout?data->set.timeout:3600; /* in seconds */
+ data->set.timeout?data->set.timeout:3600000; /* in milliseconds */
   char *line_start;
   char *host_port;
   curl_socket_t tunnelsocket = conn->sock[sockindex];
@@ -1225,15 +1225,15 @@ CURLcode Curl_proxyCONNECT(struct connec
 
       /* if timeout is requested, find out how much remaining time we have */
       long check = timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
+ Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
       if(check <=0 ) {
         failf(data, "Proxy CONNECT aborted due to timeout");
         error = SELECT_TIMEOUT; /* already too little time */
         break;
       }
 
- /* timeout each second and check the timeout */
- switch (Curl_select(tunnelsocket, CURL_SOCKET_BAD, 1000)) {
+ /* timeout each 10 milliseconds and check the timeout, FIXME: reasonable resolution? */
+ switch (Curl_select(tunnelsocket, CURL_SOCKET_BAD, 10)) {
       case -1: /* select() error, stop reading */
         error = SELECT_ERROR;
         failf(data, "Proxy CONNECT aborted due to select() error");
Index: lib/socks.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/socks.c,v
retrieving revision 1.4
diff -u -p -d -r1.4 socks.c
--- lib/socks.c 27 Oct 2006 02:18:29 -0000 1.4
+++ lib/socks.c 30 Jan 2007 09:39:03 -0000
@@ -120,14 +120,14 @@ CURLcode Curl_SOCKS4(const char *proxy_n
   /* get timeout */
   if(data->set.timeout && data->set.connecttimeout) {
     if (data->set.timeout < data->set.connecttimeout)
- timeout = data->set.timeout*1000;
+ timeout = data->set.timeout;
     else
- timeout = data->set.connecttimeout*1000;
+ timeout = data->set.connecttimeout;
   }
   else if(data->set.timeout)
- timeout = data->set.timeout*1000;
+ timeout = data->set.timeout;
   else if(data->set.connecttimeout)
- timeout = data->set.connecttimeout*1000;
+ timeout = data->set.connecttimeout;
   else
     timeout = DEFAULT_CONNECT_TIMEOUT;
 
Index: lib/ssluse.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ssluse.c,v
retrieving revision 1.164
diff -u -p -d -r1.164 ssluse.c
--- lib/ssluse.c 10 Jan 2007 21:21:53 -0000 1.164
+++ lib/ssluse.c 30 Jan 2007 09:39:09 -0000
@@ -1459,17 +1459,17 @@ Curl_ossl_connect_step2(struct connectda
   if(data->set.timeout && data->set.connecttimeout) {
     /* get the most strict timeout of the ones converted to milliseconds */
     if(data->set.timeout<data->set.connecttimeout)
- *timeout_ms = data->set.timeout*1000;
+ *timeout_ms = data->set.timeout;
     else
- *timeout_ms = data->set.connecttimeout*1000;
+ *timeout_ms = data->set.connecttimeout;
   }
   else if(data->set.timeout)
- *timeout_ms = data->set.timeout*1000;
+ *timeout_ms = data->set.timeout;
   else if(data->set.connecttimeout)
- *timeout_ms = data->set.connecttimeout*1000;
+ *timeout_ms = data->set.connecttimeout;
   else
     /* no particular time-out has been set */
- *timeout_ms= DEFAULT_CONNECT_TIMEOUT;
+ *timeout_ms = DEFAULT_CONNECT_TIMEOUT;
 
   /* Evaluate in milliseconds how much time that has passed */
   has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
Index: lib/telnet.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/telnet.c,v
retrieving revision 1.85
diff -u -p -d -r1.85 telnet.c
--- lib/telnet.c 16 Jan 2007 22:22:24 -0000 1.85
+++ lib/telnet.c 30 Jan 2007 09:39:12 -0000
@@ -1387,7 +1387,7 @@ CURLcode Curl_telnet(struct connectdata
     if(data->set.timeout) {
       struct timeval now; /* current time */
       now = Curl_tvnow();
- if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) {
+ if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
         failf(data, "Time-out");
         code = CURLE_OPERATION_TIMEOUTED;
         keepon = FALSE;
Index: lib/tftp.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/tftp.c,v
retrieving revision 1.35
diff -u -p -d -r1.35 tftp.c
--- lib/tftp.c 16 Jan 2007 22:22:24 -0000 1.35
+++ lib/tftp.c 30 Jan 2007 09:39:15 -0000
@@ -195,7 +195,7 @@ void tftp_set_timeouts(tftp_state_data_t
   else {
 
     /* Compute drop-dead time */
- maxtime = (time_t)(data->set.timeout?data->set.timeout:3600);
+ maxtime = (time_t)(data->set.timeout?data->set.timeout/1000L:3600);
     state->max_time = state->start_time+maxtime;
 
     /* Set per-block timeout to 10% of total */
Index: lib/transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.332
diff -u -p -d -r1.332 transfer.c
--- lib/transfer.c 26 Jan 2007 17:50:06 -0000 1.332
+++ lib/transfer.c 30 Jan 2007 09:39:23 -0000
@@ -1547,13 +1547,13 @@ CURLcode Curl_readwrite(struct connectda
     return result;
 
   if (data->set.timeout &&
- ((Curl_tvdiff(k->now, k->start)/1000) >= data->set.timeout)) {
+ (Curl_tvdiff(k->now, k->start) >= data->set.timeout)) {
     if (k->size != -1) {
- failf(data, "Operation timed out after %d seconds with %"
+ failf(data, "Operation timed out after %d milliseconds with %"
             FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
             data->set.timeout, k->bytecount, k->size);
     } else {
- failf(data, "Operation timed out after %d seconds with %"
+ failf(data, "Operation timed out after %d milliseconds with %"
             FORMAT_OFF_T " bytes received",
             data->set.timeout, k->bytecount);
     }
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.579
diff -u -p -d -r1.579 url.c
--- lib/url.c 28 Jan 2007 22:45:22 -0000 1.579
+++ lib/url.c 30 Jan 2007 09:39:31 -0000
@@ -1227,12 +1227,21 @@ CURLcode Curl_setopt(struct SessionHandl
      * The maximum time you allow curl to use for a single transfer
      * operation.
      */
+ data->set.timeout = va_arg(param, long) * 1000L;
+ break;
+
+ case CURLOPT_TIMEOUT_MS:
     data->set.timeout = va_arg(param, long);
     break;
+
   case CURLOPT_CONNECTTIMEOUT:
     /*
      * The maximum time you allow curl to use to connect.
      */
+ data->set.connecttimeout = va_arg(param, long) * 1000L;
+ break;
+
+ case CURLOPT_CONNECTTIMEOUT_MS:
     data->set.connecttimeout = va_arg(param, long);
     break;
 
@@ -3810,7 +3819,7 @@ else {
 
     /* alarm() makes a signal get sent when the timeout fires off, and that
        will abort system calls */
- prev_alarm = alarm((unsigned int) shortest);
+ prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest));
     /* We can expect the conn->created time to be "now", as that was just
        recently set in the beginning of this function and nothing slow
        has been done since then until now. */
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.316
diff -u -p -d -r1.316 urldata.h
--- lib/urldata.h 16 Jan 2007 22:22:25 -0000 1.316
+++ lib/urldata.h 30 Jan 2007 09:39:35 -0000
@@ -1174,8 +1174,8 @@ struct UserDefined {
 
   void *progress_client; /* pointer to pass to the progress callback */
   void *ioctl_client; /* pointer to pass to the ioctl callback */
- long timeout; /* in seconds, 0 means no timeout */
- long connecttimeout; /* in seconds, 0 means no timeout */
+ long timeout; /* in milliseconds, 0 means no timeout */
+ long connecttimeout; /* in milliseconds, 0 means no timeout */
   long ftp_response_timeout; /* in seconds, 0 means no timeout */
   curl_off_t infilesize; /* size of file to upload, -1 means unknown */
   long low_speed_limit; /* bytes/second */
Received on 2007-01-30