DEBUGASSERT(entry);
*entry = NULL; /* clear on entry */
- timeout_ms = Curl_timeleft_ms(data, TRUE);
+ timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
/* already expired! */
connclose(data->conn, "Timed out before name resolve started");
do {
- if(Curl_timeleft_ms(data, TRUE) < 0) {
+ if(Curl_timeleft_ms(data) < 0) {
failf(data, "Proxy CONNECT aborted due to timeout");
result = CURLE_OPERATION_TIMEDOUT;
goto out;
}
DEBUGASSERT(ts->authority);
- if(Curl_timeleft_ms(data, TRUE) < 0) {
+ if(Curl_timeleft_ms(data) < 0) {
failf(data, "Proxy CONNECT aborted due to timeout");
result = CURLE_OPERATION_TIMEDOUT;
goto out;
bool more_possible;
/* when do we need to be called again? */
- next_expire_ms = Curl_timeleft_ms(data, TRUE);
- if(next_expire_ms <= 0) {
+ next_expire_ms = Curl_timeleft_ms(data);
+ if(next_expire_ms < 0) {
failf(data, "Connection timeout after %" FMT_OFF_T " ms",
curlx_ptimediff_ms(Curl_pgrs_now(data),
&data->progress.t_startsingle));
if(!dns)
return CURLE_FAILED_INIT;
- if(Curl_timeleft_ms(data, TRUE) < 0) {
+ if(Curl_timeleft_ms(data) < 0) {
/* a precaution, no need to continue if time already is up */
failf(data, "Connection time-out");
return CURLE_OPERATION_TIMEDOUT;
#endif
/* check if the generic timeout possibly is set shorter */
- other_ms = Curl_timeleft_ms(data, FALSE);
+ other_ms = Curl_timeleft_ms(data);
if(other_ms && (other_ms < timeout_ms))
/* note that this also works fine for when other_ms happens to be negative
due to it already having elapsed */
*done = FALSE;
if(!Curl_shutdown_started(data, sockindex)) {
- CURL_TRC_M(data, "shutdown start on%s connection",
- sockindex ? " secondary" : "");
Curl_shutdown_start(data, sockindex, 0);
}
else {
goto out;
else {
/* check allowed time left */
- const timediff_t timeout_ms = Curl_timeleft_ms(data, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft_ms(data);
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
int rc;
* transfer/connection. If the value is 0, there is no timeout (ie there is
* infinite time left). If the value is negative, the timeout time has already
* elapsed.
- * @param data the transfer to check on
- * @param duringconnect TRUE iff connect timeout is also taken into account.
* @unittest: 1303
*/
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
- const struct curltime *pnow,
- bool duringconnect)
+ const struct curltime *pnow)
{
timediff_t timeleft_ms = 0;
timediff_t ctimeleft_ms = 0;
- timediff_t ctimeout_ms;
-
- /* The duration of a connect and the total transfer are calculated from two
- different time-stamps. It can end up with the total timeout being reached
- before the connect timeout expires and we must acknowledge whichever
- timeout that is reached first. The total timeout is set per entire
- operation, while the connect timeout is set per connect. */
- if((!data->set.timeout || data->set.connect_only) && !duringconnect)
+
+ if(Curl_shutdown_started(data, FIRSTSOCKET))
+ return Curl_shutdown_timeleft(data, data->conn, FIRSTSOCKET);
+ else if(Curl_is_connecting(data)) {
+ timediff_t ctimeout_ms = (data->set.connecttimeout > 0) ?
+ data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
+ ctimeleft_ms = ctimeout_ms -
+ curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
+ if(!ctimeleft_ms)
+ ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
+ }
+ else if(!data->set.timeout || data->set.connect_only) {
return 0; /* no timeout in place or checked, return "no limit" */
+ }
if(data->set.timeout) {
timeleft_ms = data->set.timeout -
timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
}
- if(!duringconnect)
- return timeleft_ms; /* no connect check, this is it */
- ctimeout_ms = (data->set.connecttimeout > 0) ?
- data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
- ctimeleft_ms = ctimeout_ms -
- curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
if(!ctimeleft_ms)
- ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
- if(!timeleft_ms)
- return ctimeleft_ms; /* no general timeout, this is it */
-
- /* return minimal time left or max amount already expired */
- return (ctimeleft_ms < timeleft_ms) ? ctimeleft_ms : timeleft_ms;
+ return timeleft_ms;
+ else if(!timeleft_ms)
+ return ctimeleft_ms;
+ return CURLMIN(ctimeleft_ms, timeleft_ms);
}
-timediff_t Curl_timeleft_ms(struct Curl_easy *data,
- bool duringconnect)
+timediff_t Curl_timeleft_ms(struct Curl_easy *data)
{
- return Curl_timeleft_now_ms(data, Curl_pgrs_now(data), duringconnect);
+ return Curl_timeleft_now_ms(data, Curl_pgrs_now(data));
}
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
/* Set a timer, unless we operate on the admin handle */
if(data->mid)
Curl_expire_ex(data, conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN);
+ CURL_TRC_M(data, "shutdown start on%s connection",
+ sockindex ? " secondary" : "");
}
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
bool Curl_shutdown_started(struct Curl_easy *data, int sockindex)
{
- struct curltime *pt = &data->conn->shutdown.start[sockindex];
- return (pt->tv_sec > 0) || (pt->tv_usec > 0);
+ if(data->conn) {
+ struct curltime *pt = &data->conn->shutdown.start[sockindex];
+ return (pt->tv_sec > 0) || (pt->tv_usec > 0);
+ }
+ return FALSE;
}
/* retrieves ip address and port from a sockaddr structure. note it calls
/* generic function that returns how much time there is left to run, according
to the timeouts set */
-timediff_t Curl_timeleft_ms(struct Curl_easy *data,
- bool duringconnect);
+timediff_t Curl_timeleft_ms(struct Curl_easy *data);
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
- const struct curltime *pnow,
- bool duringconnect);
+ const struct curltime *pnow);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
/* We expect to be attached when called */
DEBUGASSERT(data->conn == conn);
+ if(!Curl_shutdown_started(data, FIRSTSOCKET)) {
+ Curl_shutdown_start(data, FIRSTSOCKET, 0);
+ }
+
cshutdn_run_conn_handler(data, conn);
if(conn->bits.shutdown_filters) {
goto error;
}
- timeout_ms = Curl_timeleft_ms(data, TRUE);
- if(timeout_ms <= 0) {
+ timeout_ms = Curl_timeleft_ms(data);
+ if(timeout_ms < 0) {
result = CURLE_OPERATION_TIMEDOUT;
goto error;
}
while(!*ftpcodep && !result) {
/* check and reset timeout value every lap */
- timediff_t timeout = Curl_pp_state_timeout(data, pp, FALSE);
+ timediff_t timeout = Curl_pp_state_timeout(data, pp);
timediff_t interval_ms;
if(timeout <= 0) {
else
break;
- timeout_ms = Curl_timeleft_ms(data, FALSE);
+ timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
result = CURLE_OPERATION_TIMEDOUT;
break;
#define multi_warn_debug(x, y) Curl_nop_stmt
#endif
+bool Curl_is_connecting(struct Curl_easy *data)
+{
+ return data->mstate < MSTATE_DO;
+}
+
static CURLMcode multi_xfers_add(struct Curl_multi *multi,
struct Curl_easy *data)
{
bool *stream_error,
CURLcode *result)
{
- bool connect_timeout = data->mstate < MSTATE_DO;
timediff_t timeout_ms;
- timeout_ms = Curl_timeleft_ms(data, connect_timeout);
+ timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
/* Handle timed out */
struct curltime since;
- if(connect_timeout)
+ if(Curl_is_connecting(data))
since = data->progress.t_startsingle;
else
since = data->progress.t_startop;
void Curl_set_in_callback(struct Curl_easy *data, bool value);
bool Curl_is_in_callback(struct Curl_easy *data);
CURLcode Curl_preconnect(struct Curl_easy *data);
+bool Curl_is_connecting(struct Curl_easy *data);
void Curl_multi_connchanged(struct Curl_multi *multi);
#include "urldata.h"
#include "cfilters.h"
#include "connect.h"
+#include "multiif.h"
#include "sendf.h"
#include "curl_trc.h"
#include "select.h"
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
- struct pingpong *pp, bool disconnecting)
+ struct pingpong *pp)
{
- timediff_t timeout_ms; /* in milliseconds */
+ timediff_t timeout_ms, xfer_timeout_ms;
timediff_t response_time = data->set.server_response_timeout ?
data->set.server_response_timeout : RESP_TIMEOUT;
full response to arrive before we bail out */
timeout_ms = response_time -
curlx_ptimediff_ms(Curl_pgrs_now(data), &pp->response);
-
- if(data->set.timeout && !disconnecting) {
- /* if timeout is requested, find out how much overall remains */
- timediff_t timeout2_ms = Curl_timeleft_ms(data, FALSE);
- /* pick the lowest number */
- timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
- }
-
- if(disconnecting) {
- timediff_t total_left_ms = Curl_timeleft_ms(data, FALSE);
- timeout_ms = CURLMIN(timeout_ms, CURLMAX(total_left_ms, 0));
- }
-
+ /* transfer timeout can be 0, which means no timeout applies */
+ xfer_timeout_ms = Curl_timeleft_ms(data);
+ if(xfer_timeout_ms && (xfer_timeout_ms < timeout_ms))
+ return xfer_timeout_ms;
return timeout_ms;
}
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc;
timediff_t interval_ms;
- timediff_t timeout_ms = Curl_pp_state_timeout(data, pp, disconnecting);
+ timediff_t timeout_ms = Curl_pp_state_timeout(data, pp);
CURLcode result = CURLE_OK;
if(timeout_ms <= 0) {
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
- struct pingpong *pp, bool disconnecting);
+ struct pingpong *pp);
/***********************************************************************
*
*pnread = 0;
for(;;) {
- timediff_t timeout_ms = Curl_timeleft_ms(data, TRUE);
+ timediff_t timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
/* we already got the timeout */
return CURLE_OPERATION_TIMEDOUT;
{
time_t timeout;
timediff_t timeout_ms;
- bool start = (state->state == TFTP_STATE_START);
/* Compute drop-dead time */
- timeout_ms = Curl_timeleft_ms(state->data, start);
+ timeout_ms = Curl_timeleft_ms(state->data);
if(timeout_ms < 0) {
/* time-out, bail out, go home */
if(event)
*event = TFTP_EVENT_NONE;
- timeout_ms = Curl_timeleft_ms(state->data,
- (state->state == TFTP_STATE_START));
+ timeout_ms = Curl_timeleft_ms(state->data);
if(timeout_ms < 0) {
state->error = TFTP_ERR_TIMEOUT;
state->state = TFTP_STATE_FIN;
goto out;
if(k->keepon) {
- if(Curl_timeleft_ms(data, FALSE) < 0) {
+ if(Curl_timeleft_ms(data) < 0) {
if(k->size != -1) {
failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
" milliseconds with %" FMT_OFF_T " out of %"
{
struct hostname *ehost;
int eport;
- timediff_t timeout_ms = Curl_timeleft_ms(data, TRUE);
+ timediff_t timeout_ms = Curl_timeleft_ms(data);
const char *peertype = "host";
CURLcode result;
if(result)
break;
- left_ms = Curl_timeleft_ms(data, FALSE);
+ left_ms = Curl_timeleft_ms(data);
if(left_ms < 0) {
failf(data, "Operation timed out");
return CURLE_OPERATION_TIMEDOUT;
if(result)
break;
- left_ms = Curl_timeleft_ms(data, FALSE);
+ left_ms = Curl_timeleft_ms(data);
if(left_ms < 0) {
failf(data, "Operation timed out");
return CURLE_OPERATION_TIMEDOUT;
remaining = MAX_RENEG_BLOCK_TIME - elapsed;
if(blocking) {
- timeout_ms = Curl_timeleft_ms(data, FALSE);
+ timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
result = CURLE_OPERATION_TIMEDOUT;
while(len > *pnwritten) {
size_t this_write = 0;
int what;
- timediff_t timeout_ms = Curl_timeleft_ms(data, FALSE);
+ timediff_t timeout_ms = Curl_timeleft_ms(data);
if(timeout_ms < 0) {
/* we already got the timeout */
failf(data, "schannel: timed out sending data "
CURL_TRC_WS(data, "ws_send_raw_blocking() partial, %zu left to send",
buflen);
- left_ms = Curl_timeleft_ms(data, FALSE);
+ left_ms = Curl_timeleft_ms(data);
if(left_ms < 0) {
failf(data, "[WS] Timeout waiting for socket becoming writable");
return CURLE_SEND_ERROR;
NOW(run[i].now_s, run[i].now_us);
TIMEOUTS(run[i].timeout_ms, run[i].connecttimeout_ms);
easy->progress.now = now;
- timeout = Curl_timeleft_now_ms(easy, &now, run[i].connecting);
+ easy->mstate = run[i].connecting ? MSTATE_INIT : MSTATE_DO;
+ timeout = Curl_timeleft_now_ms(easy, &now);
if(timeout != run[i].result)
fail(run[i].comment);
}