Bug #69044 [Ana]: time_sleep_until() starts to early

From: Date: Sat, 14 Feb 2015 01:39:34 +0000
Subject: Bug #69044 [Ana]: time_sleep_until() starts to early
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-190675@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69044&edit=1 ID: 69044 Updated by: yohgaki@php.net Reported by: marc at gutt dot it Summary: time_sleep_until() starts to early Status: Analyzed Type: Bug Package: Date/time related Operating System: Debian PHP Version: 5.4.37 Block user comment: N Private report: N New Comment: My previous analysis is wrong. time_sleep_until() sleeps as it supposed. It seems date() is doing something wrong. Previous Comments: ------------------------------------------------------------------------ [2015-02-14 00:47:54] yohgaki@php.net Oops. Round margin should be something like 0.99. Or use ceil() to be precise. ------------------------------------------------------------------------ [2015-02-14 00:45:32] yohgaki@php.net The cause of this is floating point calculation. It's rounded. Possible patch is diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 2b70414..44a41e4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4486,8 +4486,8 @@ PHP_FUNCTION(time_sleep_until) 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); + /* 1sec = 1000000000 nanoseconds. Add 0.5 sec round margin */ + php_req.tv_nsec = (long) ((c_ts - php_req.tv_sec) * 1000000000.00 + 0.5) ; while (nanosleep(&php_req, &php_rem)) { if (errno == EINTR) { ------------------------------------------------------------------------ [2015-02-12 21:08:43] marc at gutt dot it Description: ------------ --- From manual page: http://www.php.net/function.time-sleep-until --- time_sleep_until() starts one second to early. Test script: --------------- <?php $sleep_until = mktime(date('H'), date('i'), date('s') + 15); echo "sleep until " . date('c', $sleep_until) . "\n"; time_sleep_until($sleep_until); echo "woke up at " . date('c'); /* returns: sleep until 2015-02-12T22:01:19+01:00 woke up at 2015-02-12T22:01:18+01:00 */ ?> ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=69044&edit=1

« previous php.bugs (#190675) next »