time-keeping: keep timestamp in multi, always update

Always use curlx_now() when calling Curl_pgrs_now(data). Tests with the
"manual" updates to now proved differ more then 100ms in parallel testing.

Add `curlx_nowp()` to set current time into a struct curltime.
Add `curlx_ptimediff_ms() and friends, passing pointers.

Update documentation.

Closes #19998
This commit is contained in:
Stefan Eissing 2025-12-18 13:55:07 +01:00 committed by Daniel Stenberg
parent 308c347c8b
commit b4be1f271e
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
61 changed files with 471 additions and 502 deletions

View file

@ -311,7 +311,8 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
/* This is only set to non-zero if the timer was started. */
(ares->happy_eyeballs_dns_time.tv_sec ||
ares->happy_eyeballs_dns_time.tv_usec) &&
(curlx_timediff_ms(data->progress.now, ares->happy_eyeballs_dns_time) >=
(curlx_ptimediff_ms(Curl_pgrs_now(data),
&ares->happy_eyeballs_dns_time) >=
HAPPY_EYEBALLS_DNS_TIMEOUT)) {
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
running. */
@ -439,14 +440,13 @@ CURLcode Curl_async_await(struct Curl_easy *data,
result = CURLE_ABORTED_BY_CALLBACK;
else {
struct curltime now = curlx_now(); /* update in loop */
timediff_t elapsed_ms = curlx_timediff_ms(now, data->progress.now);
timediff_t elapsed_ms = curlx_ptimediff_ms(&now, Curl_pgrs_now(data));
if(elapsed_ms <= 0)
timeout_ms -= 1; /* always deduct at least 1 */
else if(elapsed_ms > timeout_ms)
timeout_ms = -1;
else
timeout_ms -= elapsed_ms;
Curl_pgrs_now_at_least(data, &now);
}
if(timeout_ms < 0)
result = CURLE_OPERATION_TIMEDOUT;
@ -582,7 +582,7 @@ static void async_ares_hostbyname_cb(void *user_data,
timeout to prevent it. After all, we do not even know where in the
c-ares retry cycle each request is.
*/
ares->happy_eyeballs_dns_time = data->progress.now;
ares->happy_eyeballs_dns_time = *Curl_pgrs_now(data);
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
}
}