aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-02-05 22:51:32 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-02-05 22:51:32 +0000
commit91386937ff120d11f7bf24dc487f00751362a61c (patch)
tree9affbbce6d62c6082ef11430b84f6c6eaa071de7 /lib
parent0fc51ac5a6e9cca55398cabfafd4effdb3df21fe (diff)
- Michael Wallner provided a patch that adds support for CURLOPT_TIMEOUT_MS
and CURLOPT_CONNECTTIMEOUT_MS that, as their names should hint, do the timeouts with millisecond resolution instead. The only restriction to that is the alarm() (sometimes) used to abort name resolves as that uses full seconds. I fixed the FTP response timeout part of the patch. Internally we now count and keep the timeouts in milliseconds but it also means we multiply set timeouts with 1000. The effect of this is that no timeout can be set to more than 2^31 milliseconds (on 32 bit systems), which equals 24.86 days. We probably couldn't before either since the code did *1000 on the timeout values on several places already.
Diffstat (limited to 'lib')
-rw-r--r--lib/connect.c18
-rw-r--r--lib/ftp.c24
-rw-r--r--lib/gtls.c6
-rw-r--r--lib/hostares.c12
-rw-r--r--lib/hostthre.c4
-rw-r--r--lib/http.c11
-rw-r--r--lib/socks.c10
-rw-r--r--lib/ssluse.c10
-rw-r--r--lib/telnet.c2
-rw-r--r--lib/tftp.c2
-rw-r--r--lib/transfer.c6
-rw-r--r--lib/url.c18
-rw-r--r--lib/urldata.h6
13 files changed, 70 insertions, 59 deletions
diff --git a/lib/connect.c b/lib/connect.c
index 2b3897204..37db6e228 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -558,15 +558,15 @@ CURLcode Curl_is_connected(struct connectdata *conn,
/* 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 connectdata *conn, /* context */
/* 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;
diff --git a/lib/ftp.c b/lib/ftp.c
index 479eeffe3..29004ead3 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -184,7 +184,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
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(struct connectdata *conn)
/* 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 */
@@ -444,7 +444,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
bool keepon=TRUE;
ssize_t gotbytes;
char *ptr;
- long timeout; /* timeout in seconds */
+ long timeout; /* timeout in milliseconds */
int interval_ms;
struct SessionHandle *data = conn->data;
char *line_start;
@@ -473,16 +473,16 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
the response for any given ftp response, not for the time
from connect to the given ftp response. */
timeout = data->set.ftp_response_timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
+ Curl_tvdiff(Curl_tvnow(), now); /* spent time */
else if(data->set.timeout)
/* if timeout is requested, find out how much remaining time we have */
timeout = data->set.timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
+ Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
else
/* Even without a requested timeout, we only wait response_time
seconds for the full response to arrive before we bail out */
timeout = ftpc->response_time -
- Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
+ Curl_tvdiff(Curl_tvnow(), now); /* spent time */
if(timeout <=0 ) {
failf(data, "FTP response timeout");
@@ -491,6 +491,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
if(!ftpc->cache) {
interval_ms = 1 * 1000; /* use 1 second timeout intervals */
+ if(timeout < interval_ms)
+ interval_ms = timeout;
switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) {
case -1: /* select() error, stop reading */
@@ -2751,16 +2753,16 @@ static long ftp_state_timeout(struct connectdata *conn)
time. Also, use ftp->response because FTP_RESPONSE_TIMEOUT is supposed
to govern the response for any given ftp response, not for the time
from connect to the given ftp response. */
- timeout_ms = data->set.ftp_response_timeout*1000 - /* timeout time */
+ timeout_ms = data->set.ftp_response_timeout - /* timeout time */
Curl_tvdiff(Curl_tvnow(), ftpc->response); /* spent time */
else if(data->set.timeout)
/* if timeout is requested, find out how much remaining time we have */
- timeout_ms = data->set.timeout*1000 - /* timeout time */
+ timeout_ms = data->set.timeout - /* timeout time */
Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
else
/* Without a requested timeout, we only wait 'response_time' seconds for
the full response to arrive before we bail out */
- timeout_ms = ftpc->response_time*1000 -
+ timeout_ms = ftpc->response_time -
Curl_tvdiff(Curl_tvnow(), ftpc->response); /* spent time */
return timeout_ms;
@@ -2904,7 +2906,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
/* We always support persistant connections on ftp */
conn->bits.close = FALSE;
- ftpc->response_time = 3600; /* set default response time-out */
+ ftpc->response_time = 3600000; /* set default response time-out */
#ifndef CURL_DISABLE_HTTP
if (conn->bits.tunnel_proxy && conn->bits.httpproxy) {
@@ -3063,7 +3065,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature
*/
long old_time = ftpc->response_time;
- ftpc->response_time = 60; /* give it only a minute for now */
+ ftpc->response_time = 60000; /* give it only a minute for now */
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
diff --git a/lib/gtls.c b/lib/gtls.c
index 250ecada4..977263b12 100644
--- a/lib/gtls.c
+++ b/lib/gtls.c
@@ -144,12 +144,12 @@ static CURLcode handshake(struct connectdata *conn,
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 */
diff --git a/lib/hostares.c b/lib/hostares.c
index 1db0f4320..2738edcdf 100644
--- a/lib/hostares.c
+++ b/lib/hostares.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -183,7 +183,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
{
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 connectdata *conn,
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) {
diff --git a/lib/hostthre.c b/lib/hostthre.c
index 12e31ea34..f88bf15ec 100644
--- a/lib/hostthre.c
+++ b/lib/hostthre.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -600,7 +600,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
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);
diff --git a/lib/http.c b/lib/http.c
index c07053bdd..ad42273cd 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1121,7 +1121,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
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,16 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
/* 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 */
- if(check <=0 ) {
+ 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)) {
+ /* loop every second at least, less if the timeout is near */
+ switch (Curl_select(tunnelsocket, CURL_SOCKET_BAD,
+ check<1000?check:1000)) {
case -1: /* select() error, stop reading */
error = SELECT_ERROR;
failf(data, "Proxy CONNECT aborted due to select() error");
diff --git a/lib/socks.c b/lib/socks.c
index 3319e697e..32d0c4b54 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -120,14 +120,14 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
/* 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;
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 55afb2446..4f5b7f94d 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -1459,17 +1459,17 @@ Curl_ossl_connect_step2(struct connectdata *conn,
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);
diff --git a/lib/telnet.c b/lib/telnet.c
index 97d22b788..14501c624 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1387,7 +1387,7 @@ CURLcode Curl_telnet(struct connectdata *conn, bool *done)
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;
diff --git a/lib/tftp.c b/lib/tftp.c
index 2a28b0cb9..b1a34a5df 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -195,7 +195,7 @@ void tftp_set_timeouts(tftp_state_data_t *state)
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 */
diff --git a/lib/transfer.c b/lib/transfer.c
index bff16b4ff..91e468b64 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1547,13 +1547,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
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);
}
diff --git a/lib/url.c b/lib/url.c
index 8b49033f3..076f50ebd 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -734,7 +734,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* An FTP option that specifies how quickly an FTP response must be
* obtained before it is considered failure.
*/
- data->set.ftp_response_timeout = va_arg( param , long );
+ data->set.ftp_response_timeout = va_arg( param , long ) * 1000;
break;
case CURLOPT_FTPLISTONLY:
/*
@@ -1242,12 +1242,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* 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;
@@ -3828,9 +3837,14 @@ else {
/* if timeout is not set, use the connect timeout */
shortest = data->set.connecttimeout;
+ if(shortest < 1000)
+ /* the alarm() function only provide integer second resolution, so if
+ we want to wait less than one second we must bail out already now. */
+ return CURLE_OPERATION_TIMEDOUT;
+
/* 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. */
diff --git a/lib/urldata.h b/lib/urldata.h
index 3bb3327ba..acc9d1ba6 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1176,9 +1176,9 @@ 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 ftp_response_timeout; /* 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 milliseconds, 0 means no timeout */
curl_off_t infilesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */