mirror of
https://github.com/curl/curl.git
synced 2026-08-25 14:13:34 +03:00
lib: keep timestamp in easy handle
Use `data->progress.now` as the timestamp of proecssing a transfer. Update it on significant events and refrain from calling `curlx_now()` in many places. The problem this addresses is a) calling curlx_now() has costs, depending on platform. Calling it every time results in 25% increase `./runtest` duration on macOS. b) we used to pass a `struct curltime *` around to save on calls, but when some method directly use `curx_now()` and some use the passed pointer, the transfer experienes non-linear time. This results in timeline checks to report events in the wrong order. By keeping a timestamp in the easy handle and updating it there, no longer invoking `curlx_now()` in the "lower" methods, the transfer can observer a steady clock progression. Add documentation in docs/internals/TIME-KEEPING.md Reported-by: Viktor Szakats Fixes #19935 Closes #19961
This commit is contained in:
parent
425a2aa1af
commit
2de22a00c7
67 changed files with 598 additions and 458 deletions
|
|
@ -1074,7 +1074,7 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
|||
|
||||
(void)data;
|
||||
DEBUGASSERT(ctx->sock == CURL_SOCKET_BAD);
|
||||
ctx->started_at = curlx_now();
|
||||
ctx->started_at = data->progress.now;
|
||||
#ifdef SOCK_NONBLOCK
|
||||
/* Do not tuck SOCK_NONBLOCK into socktype when opensocket callback is set
|
||||
* because we would not know how socketype is about to be used in the
|
||||
|
|
@ -1201,7 +1201,7 @@ out:
|
|||
}
|
||||
else if(isconnected) {
|
||||
set_local_ip(cf, data);
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = data->progress.now;
|
||||
cf->connected = TRUE;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" FMT_SOCKET_T,
|
||||
|
|
@ -1320,7 +1320,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
|
|||
else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) {
|
||||
if(verifyconnect(ctx->sock, &ctx->error)) {
|
||||
/* we are connected with TCP, awesome! */
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = data->progress.now;
|
||||
set_local_ip(cf, data);
|
||||
*done = TRUE;
|
||||
cf->connected = TRUE;
|
||||
|
|
@ -1396,13 +1396,13 @@ static CURLcode cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
|||
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
|
||||
#endif
|
||||
|
||||
static void win_update_sndbuf_size(struct cf_socket_ctx *ctx)
|
||||
static void win_update_sndbuf_size(struct Curl_easy *data,
|
||||
struct cf_socket_ctx *ctx)
|
||||
{
|
||||
ULONG ideal;
|
||||
DWORD ideallen;
|
||||
struct curltime n = curlx_now();
|
||||
|
||||
if(curlx_timediff_ms(n, ctx->last_sndbuf_query_at) > 1000) {
|
||||
if(curlx_timediff_ms(data->progress.now, ctx->last_sndbuf_query_at) > 1000) {
|
||||
if(!WSAIoctl(ctx->sock, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
|
||||
&ideal, sizeof(ideal), &ideallen, 0, 0) &&
|
||||
ideal != ctx->sndbuf_size &&
|
||||
|
|
@ -1410,7 +1410,7 @@ static void win_update_sndbuf_size(struct cf_socket_ctx *ctx)
|
|||
(const char *)&ideal, sizeof(ideal))) {
|
||||
ctx->sndbuf_size = ideal;
|
||||
}
|
||||
ctx->last_sndbuf_query_at = n;
|
||||
ctx->last_sndbuf_query_at = data->progress.now;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1491,7 +1491,7 @@ static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
|
||||
#ifdef USE_WINSOCK
|
||||
if(!result)
|
||||
win_update_sndbuf_size(ctx);
|
||||
win_update_sndbuf_size(data, ctx);
|
||||
#endif
|
||||
|
||||
CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, %zu",
|
||||
|
|
@ -1557,7 +1557,7 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
|
||||
CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, %zu", len, result, *pnread);
|
||||
if(!result && !ctx->got_first_byte) {
|
||||
ctx->first_byte_at = curlx_now();
|
||||
ctx->first_byte_at = data->progress.now;
|
||||
ctx->got_first_byte = TRUE;
|
||||
}
|
||||
return result;
|
||||
|
|
@ -1990,23 +1990,21 @@ static timediff_t cf_tcp_accept_timeleft(struct Curl_cfilter *cf,
|
|||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
|
||||
timediff_t other_ms;
|
||||
struct curltime now;
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
if(data->set.accepttimeout > 0)
|
||||
timeout_ms = data->set.accepttimeout;
|
||||
#endif
|
||||
|
||||
now = curlx_now();
|
||||
/* check if the generic timeout possibly is set shorter */
|
||||
other_ms = Curl_timeleft_ms(data, &now, FALSE);
|
||||
other_ms = Curl_timeleft_ms(data, FALSE);
|
||||
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 */
|
||||
timeout_ms = other_ms;
|
||||
else {
|
||||
/* subtract elapsed time */
|
||||
timeout_ms -= curlx_timediff_ms(now, ctx->started_at);
|
||||
timeout_ms -= curlx_timediff_ms(data->progress.now, ctx->started_at);
|
||||
if(!timeout_ms)
|
||||
/* avoid returning 0 as that means no timeout! */
|
||||
timeout_ms = -1;
|
||||
|
|
@ -2142,7 +2140,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
|||
cf_tcp_set_accepted_remote_ip(cf, data);
|
||||
set_local_ip(cf, data);
|
||||
ctx->active = TRUE;
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = data->progress.now;
|
||||
cf->connected = TRUE;
|
||||
CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T
|
||||
", remote=%s port=%d)",
|
||||
|
|
@ -2208,7 +2206,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
|
|||
goto out;
|
||||
Curl_conn_cf_add(data, conn, sockindex, cf);
|
||||
|
||||
ctx->started_at = curlx_now();
|
||||
ctx->started_at = data->progress.now;
|
||||
conn->sock[sockindex] = ctx->sock;
|
||||
set_local_ip(cf, data);
|
||||
CURL_TRC_CF(data, cf, "set filter for listen socket fd=%" FMT_SOCKET_T
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue