From: Nikita Popov Date: Sun, 16 Jun 2019 14:14:30 +0000 (+0200) Subject: Use uint64_t for time_sleep_until calculations X-Git-Tag: php-7.4.0alpha2~80 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4befe320e31533f7854d9e972aafd81119daab25;p=php Use uint64_t for time_sleep_until calculations --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 8d4dec48c1..9188b5b097 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4637,30 +4637,30 @@ PHP_FUNCTION(time_nanosleep) Make the script sleep until the specified time */ PHP_FUNCTION(time_sleep_until) { - double d_ts, c_ts; + double target_secs; struct timeval tm; struct timespec php_req, php_rem; + uint64_t current_ns, target_ns, diff_ns; + const uint64_t ns_per_sec = 1000000000; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_DOUBLE(d_ts) + Z_PARAM_DOUBLE(target_secs) ZEND_PARSE_PARAMETERS_END(); if (gettimeofday((struct timeval *) &tm, NULL) != 0) { RETURN_FALSE; } - c_ts = (double)(d_ts - tm.tv_sec - tm.tv_usec / 1000000.00); - if (c_ts < 0) { + target_ns = (uint64_t) (target_secs * ns_per_sec); + current_ns = ((uint64_t) tm.tv_sec) * ns_per_sec + ((uint64_t) tm.tv_usec) * 1000; + if (target_ns < current_ns) { php_error_docref(NULL, E_WARNING, "Sleep until to time is less than current time"); RETURN_FALSE; } - php_req.tv_sec = (time_t) c_ts; - if (php_req.tv_sec > c_ts) { /* rounding up occurred */ - php_req.tv_sec--; - } - /* 1sec = 1000000000 nanoseconds */ - php_req.tv_nsec = (long) ((c_ts - php_req.tv_sec) * 1000000000.00); + diff_ns = target_ns - current_ns; + php_req.tv_sec = (time_t) (diff_ns / ns_per_sec); + php_req.tv_nsec = (long) (diff_ns % ns_per_sec); while (nanosleep(&php_req, &php_rem)) { if (errno == EINTR) { diff --git a/ext/standard/tests/misc/time_sleep_until_basic.phpt b/ext/standard/tests/misc/time_sleep_until_basic.phpt index 7f35677d1e..cac7133e95 100644 --- a/ext/standard/tests/misc/time_sleep_until_basic.phpt +++ b/ext/standard/tests/misc/time_sleep_until_basic.phpt @@ -32,5 +32,3 @@ Michele Orselli mo@ideato.it --EXPECT-- bool(true) bool(true) ---XFAIL-- -gettimeofday cannot be used to reliably implement high precision process synchronization