Skip to content

Commit 4befe32

Browse files
nikickrakjoe
authored andcommitted
Use uint64_t for time_sleep_until calculations
1 parent 11c3215 commit 4befe32

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

ext/standard/basic_functions.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4637,30 +4637,30 @@ PHP_FUNCTION(time_nanosleep)
46374637
Make the script sleep until the specified time */
46384638
PHP_FUNCTION(time_sleep_until)
46394639
{
4640-
double d_ts, c_ts;
4640+
double target_secs;
46414641
struct timeval tm;
46424642
struct timespec php_req, php_rem;
4643+
uint64_t current_ns, target_ns, diff_ns;
4644+
const uint64_t ns_per_sec = 1000000000;
46434645

46444646
ZEND_PARSE_PARAMETERS_START(1, 1)
4645-
Z_PARAM_DOUBLE(d_ts)
4647+
Z_PARAM_DOUBLE(target_secs)
46464648
ZEND_PARSE_PARAMETERS_END();
46474649

46484650
if (gettimeofday((struct timeval *) &tm, NULL) != 0) {
46494651
RETURN_FALSE;
46504652
}
46514653

4652-
c_ts = (double)(d_ts - tm.tv_sec - tm.tv_usec / 1000000.00);
4653-
if (c_ts < 0) {
4654+
target_ns = (uint64_t) (target_secs * ns_per_sec);
4655+
current_ns = ((uint64_t) tm.tv_sec) * ns_per_sec + ((uint64_t) tm.tv_usec) * 1000;
4656+
if (target_ns < current_ns) {
46544657
php_error_docref(NULL, E_WARNING, "Sleep until to time is less than current time");
46554658
RETURN_FALSE;
46564659
}
46574660

4658-
php_req.tv_sec = (time_t) c_ts;
4659-
if (php_req.tv_sec > c_ts) { /* rounding up occurred */
4660-
php_req.tv_sec--;
4661-
}
4662-
/* 1sec = 1000000000 nanoseconds */
4663-
php_req.tv_nsec = (long) ((c_ts - php_req.tv_sec) * 1000000000.00);
4661+
diff_ns = target_ns - current_ns;
4662+
php_req.tv_sec = (time_t) (diff_ns / ns_per_sec);
4663+
php_req.tv_nsec = (long) (diff_ns % ns_per_sec);
46644664

46654665
while (nanosleep(&php_req, &php_rem)) {
46664666
if (errno == EINTR) {

ext/standard/tests/misc/time_sleep_until_basic.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,3 @@ Michele Orselli [email protected]
3232
--EXPECT--
3333
bool(true)
3434
bool(true)
35-
--XFAIL--
36-
gettimeofday cannot be used to reliably implement high precision process synchronization

0 commit comments

Comments
 (0)