1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-10 19:45:04 -05:00

timediff: make it 64 bit (if possible) even with 32 bit time_t

... to make it hold microseconds too.

Fixes #4165
Closes #4168
This commit is contained in:
Daniel Stenberg 2019-07-31 15:30:31 +02:00
parent 7c14dde924
commit b1616dad8f
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
15 changed files with 53 additions and 57 deletions

View File

@ -603,8 +603,9 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
} }
else { else {
/* poll for name lookup done with exponential backoff up to 250ms */ /* poll for name lookup done with exponential backoff up to 250ms */
timediff_t elapsed = Curl_timediff(Curl_now(), /* should be fine even if this converts to 32 bit */
data->progress.t_startsingle); time_t elapsed = (time_t)Curl_timediff(Curl_now(),
data->progress.t_startsingle);
if(elapsed < 0) if(elapsed < 0)
elapsed = 0; elapsed = 0;
@ -651,7 +652,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
if(ms < 3) if(ms < 3)
milli = 0; milli = 0;
else if(ms <= 50) else if(ms <= 50)
milli = ms/3; milli = (time_t)ms/3;
else if(ms <= 250) else if(ms <= 250)
milli = 50; milli = 50;
else else

View File

@ -795,8 +795,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(rc == 0) { /* no connection yet */ if(rc == 0) { /* no connection yet */
error = 0; error = 0;
if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) { if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
infof(data, "After %ldms connect time, move on!\n", infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
conn->timeoutms_per_addr); "ms connect time, move on!\n", conn->timeoutms_per_addr);
error = ETIMEDOUT; error = ETIMEDOUT;
} }
@ -862,11 +862,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
Curl_strerror(error, buffer, sizeof(buffer))); Curl_strerror(error, buffer, sizeof(buffer)));
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ? conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
allow : allow / 2; allow : allow / 2;
status = trynextip(conn, sockindex, i); status = trynextip(conn, sockindex, i);
if(status != CURLE_COULDNT_CONNECT if((status != CURLE_COULDNT_CONNECT) ||
|| conn->tempsock[other] == CURL_SOCKET_BAD) conn->tempsock[other] == CURL_SOCKET_BAD)
/* the last attempt failed and no other sockets remain open */ /* the last attempt failed and no other sockets remain open */
result = status; result = status;
} }

View File

@ -380,7 +380,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
struct ftp_conn *ftpc = &conn->proto.ftpc; struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp; struct pingpong *pp = &ftpc->pp;
int result; int result;
time_t timeout_ms; timediff_t timeout_ms;
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
@ -491,7 +491,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
{ {
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
time_t timeout_ms; timediff_t timeout_ms;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
*connected = FALSE; *connected = FALSE;

View File

@ -624,7 +624,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
const char *hostname, const char *hostname,
int port, int port,
struct Curl_dns_entry **entry, struct Curl_dns_entry **entry,
time_t timeoutms) timediff_t timeoutms)
{ {
#ifdef USE_ALARM_TIMEOUT #ifdef USE_ALARM_TIMEOUT
#ifdef HAVE_SIGACTION #ifdef HAVE_SIGACTION

View File

@ -25,6 +25,7 @@
#include "curl_setup.h" #include "curl_setup.h"
#include "hash.h" #include "hash.h"
#include "curl_addrinfo.h" #include "curl_addrinfo.h"
#include "timeval.h" /* for timediff_t */
#include "asyn.h" #include "asyn.h"
#ifdef HAVE_SETJMP_H #ifdef HAVE_SETJMP_H
@ -89,7 +90,7 @@ int Curl_resolv(struct connectdata *conn,
struct Curl_dns_entry **dnsentry); struct Curl_dns_entry **dnsentry);
int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
int port, struct Curl_dns_entry **dnsentry, int port, struct Curl_dns_entry **dnsentry,
time_t timeoutms); timediff_t timeoutms);
#ifdef CURLRES_IPV6 #ifdef CURLRES_IPV6
/* /*

View File

@ -233,7 +233,7 @@ static unsigned int http2_conncheck(struct connectdata *check,
if(checks_to_perform & CONNCHECK_KEEPALIVE) { if(checks_to_perform & CONNCHECK_KEEPALIVE) {
struct curltime now = Curl_now(); struct curltime now = Curl_now();
time_t elapsed = Curl_timediff(now, check->keepalive); timediff_t elapsed = Curl_timediff(now, check->keepalive);
if(elapsed > check->upkeep_interval_ms) { if(elapsed > check->upkeep_interval_ms) {
/* Perform an HTTP/2 PING */ /* Perform an HTTP/2 PING */

View File

@ -2838,7 +2838,7 @@ multi_addtimeout(struct Curl_easy *data,
* *
* Expire replaces a former timeout using the same id if already set. * Expire replaces a former timeout using the same id if already set.
*/ */
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id) void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
{ {
struct Curl_multi *multi = data->multi; struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime; struct curltime *nowp = &data->state.expiretime;
@ -2852,7 +2852,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
DEBUGASSERT(id < EXPIRE_LAST); DEBUGASSERT(id < EXPIRE_LAST);
set = Curl_now(); set = Curl_now();
set.tv_sec += milli/1000; set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */
set.tv_usec += (unsigned int)(milli%1000)*1000; set.tv_usec += (unsigned int)(milli%1000)*1000;
if(set.tv_usec >= 1000000) { if(set.tv_usec >= 1000000) {

View File

@ -27,7 +27,7 @@
*/ */
void Curl_updatesocket(struct Curl_easy *data); void Curl_updatesocket(struct Curl_easy *data);
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id); void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
void Curl_expire_clear(struct Curl_easy *data); void Curl_expire_clear(struct Curl_easy *data);
void Curl_expire_done(struct Curl_easy *data, expire_id id); void Curl_expire_done(struct Curl_easy *data, expire_id id);
void Curl_update_timer(struct Curl_multi *multi); void Curl_update_timer(struct Curl_multi *multi);

View File

@ -60,12 +60,12 @@ time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
/* Without a requested timeout, we only wait 'response_time' seconds for the /* Without a requested timeout, we only wait 'response_time' seconds for the
full response to arrive before we bail out */ full response to arrive before we bail out */
timeout_ms = response_time - timeout_ms = response_time -
Curl_timediff(Curl_now(), pp->response); /* spent time */ (time_t)Curl_timediff(Curl_now(), pp->response); /* spent time */
if(data->set.timeout && !disconnecting) { if(data->set.timeout && !disconnecting) {
/* if timeout is requested, find out how much remaining time we have */ /* if timeout is requested, find out how much remaining time we have */
time_t timeout2_ms = data->set.timeout - /* timeout time */ time_t timeout2_ms = data->set.timeout - /* timeout time */
Curl_timediff(Curl_now(), conn->now); /* spent time */ (time_t)Curl_timediff(Curl_now(), conn->now); /* spent time */
/* pick the lowest number */ /* pick the lowest number */
timeout_ms = CURLMIN(timeout_ms, timeout2_ms); timeout_ms = CURLMIN(timeout_ms, timeout2_ms);

View File

@ -26,6 +26,7 @@
#include "sendf.h" #include "sendf.h"
#include "multiif.h" #include "multiif.h"
#include "progress.h" #include "progress.h"
#include "timeval.h"
#include "curl_printf.h" #include "curl_printf.h"
/* check rate limits within this many recent milliseconds, at minimum. */ /* check rate limits within this many recent milliseconds, at minimum. */
@ -168,7 +169,7 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
void Curl_pgrsTime(struct Curl_easy *data, timerid timer) void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
{ {
struct curltime now = Curl_now(); struct curltime now = Curl_now();
time_t *delta = NULL; timediff_t *delta = NULL;
switch(timer) { switch(timer) {
default: default:
@ -270,8 +271,8 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
struct curltime now) struct curltime now)
{ {
curl_off_t size = cursize - startsize; curl_off_t size = cursize - startsize;
time_t minimum; timediff_t minimum;
time_t actual; timediff_t actual;
if(!limit || !size) if(!limit || !size)
return 0; return 0;
@ -284,10 +285,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit); minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
else { else {
minimum = (time_t) (size / limit); minimum = (time_t) (size / limit);
if(minimum < TIME_T_MAX/1000) if(minimum < TIMEDIFF_T_MAX/1000)
minimum *= 1000; minimum *= 1000;
else else
minimum = TIME_T_MAX; minimum = TIMEDIFF_T_MAX;
} }
/* /*

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -77,9 +77,9 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
time_t timeout_ms); time_t timeout_ms);
#define SOCKET_READABLE(x,z) \ #define SOCKET_READABLE(x,z) \
Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z) Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, (time_t)z)
#define SOCKET_WRITABLE(x,z) \ #define SOCKET_WRITABLE(x,z) \
Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z) Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, (time_t)z)
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);

View File

@ -174,14 +174,6 @@ struct curltime Curl_now(void)
#endif #endif
#if SIZEOF_TIME_T < 8
#define TIME_MAX INT_MAX
#define TIME_MIN INT_MIN
#else
#define TIME_MAX 9223372036854775807LL
#define TIME_MIN -9223372036854775807LL
#endif
/* /*
* Returns: time difference in number of milliseconds. For too large diffs it * Returns: time difference in number of milliseconds. For too large diffs it
* returns max value. * returns max value.
@ -191,10 +183,10 @@ struct curltime Curl_now(void)
timediff_t Curl_timediff(struct curltime newer, struct curltime older) timediff_t Curl_timediff(struct curltime newer, struct curltime older)
{ {
timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
if(diff >= (TIME_MAX/1000)) if(diff >= (TIMEDIFF_T_MAX/1000))
return TIME_MAX; return TIMEDIFF_T_MAX;
else if(diff <= (TIME_MIN/1000)) else if(diff <= (TIMEDIFF_T_MIN/1000))
return TIME_MIN; return TIMEDIFF_T_MIN;
return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000; return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
} }
@ -205,9 +197,9 @@ timediff_t Curl_timediff(struct curltime newer, struct curltime older)
timediff_t Curl_timediff_us(struct curltime newer, struct curltime older) timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
{ {
timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
if(diff >= (TIME_MAX/1000000)) if(diff >= (TIMEDIFF_T_MAX/1000000))
return TIME_MAX; return TIMEDIFF_T_MAX;
else if(diff <= (TIME_MIN/1000000)) else if(diff <= (TIMEDIFF_T_MIN/1000000))
return TIME_MIN; return TIMEDIFF_T_MIN;
return diff * 1000000 + newer.tv_usec-older.tv_usec; return diff * 1000000 + newer.tv_usec-older.tv_usec;
} }

View File

@ -24,13 +24,13 @@
#include "curl_setup.h" #include "curl_setup.h"
#if SIZEOF_TIME_T < 8 /* Use a larger type even for 32 bit time_t systems so that we can keep
typedef int timediff_t; microsecond accuracy in it */
#define CURL_FORMAT_TIMEDIFF_T "d"
#else
typedef curl_off_t timediff_t; typedef curl_off_t timediff_t;
#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T #define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
#endif
#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
struct curltime { struct curltime {
time_t tv_sec; /* seconds */ time_t tv_sec; /* seconds */

View File

@ -972,7 +972,8 @@ static int call_extract_if_dead(struct connectdata *conn, void *param)
static void prune_dead_connections(struct Curl_easy *data) static void prune_dead_connections(struct Curl_easy *data)
{ {
struct curltime now = Curl_now(); struct curltime now = Curl_now();
time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup); timediff_t elapsed =
Curl_timediff(now, data->state.conn_cache->last_cleanup);
if(elapsed >= 1000L) { if(elapsed >= 1000L) {
struct prunedead prune; struct prunedead prune;

View File

@ -909,8 +909,8 @@ struct connectdata {
struct curltime connecttime; struct curltime connecttime;
/* The two fields below get set in Curl_connecthost */ /* The two fields below get set in Curl_connecthost */
int num_addr; /* number of addresses to try to connect to */ int num_addr; /* number of addresses to try to connect to */
time_t timeoutms_per_addr; /* how long time in milliseconds to spend on timediff_t timeoutms_per_addr; /* how long time in milliseconds to spend on
trying to connect to each IP address */ trying to connect to each IP address */
const struct Curl_handler *handler; /* Connection's protocol handler */ const struct Curl_handler *handler; /* Connection's protocol handler */
const struct Curl_handler *given; /* The protocol first given */ const struct Curl_handler *given; /* The protocol first given */
@ -1108,17 +1108,17 @@ struct Progress {
int width; /* screen width at download start */ int width; /* screen width at download start */
int flags; /* see progress.h */ int flags; /* see progress.h */
time_t timespent; timediff_t timespent;
curl_off_t dlspeed; curl_off_t dlspeed;
curl_off_t ulspeed; curl_off_t ulspeed;
time_t t_nslookup; timediff_t t_nslookup;
time_t t_connect; timediff_t t_connect;
time_t t_appconnect; timediff_t t_appconnect;
time_t t_pretransfer; timediff_t t_pretransfer;
time_t t_starttransfer; timediff_t t_starttransfer;
time_t t_redirect; timediff_t t_redirect;
struct curltime start; struct curltime start;
struct curltime t_startsingle; struct curltime t_startsingle;