Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions ext/standard/basic_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,18 +1131,34 @@ PHP_FUNCTION(flush)
/* {{{ Delay for a given number of seconds */
PHP_FUNCTION(sleep)
{
zend_long num;
zval *num;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_LONG(num)
Z_PARAM_NUMBER(num)
ZEND_PARSE_PARAMETERS_END();

if (num < 0) {
zend_argument_value_error(1, "must be greater than or equal to 0");
RETURN_THROWS();
}

RETURN_LONG(php_sleep((unsigned int)num));
if (Z_TYPE_P(num) == IS_DOUBLE) {
const double seconds = Z_DVAL_P(num);
if (UNEXPECTED(seconds < 0)) {
zend_argument_value_error(1, "must be greater than or equal to 0");
RETURN_THROWS();
}
#ifdef HAVE_USLEEP
const unsigned int fraction_microseconds = (unsigned int)((seconds - (unsigned int)seconds) * 1000000);
if(fraction_microseconds > 0) {
usleep(fraction_microseconds);
}
#endif
RETURN_LONG(php_sleep((unsigned int)seconds));
} else {
ZEND_ASSERT(Z_TYPE_P(num) == IS_LONG);
zend_long seconds = Z_LVAL_P(num);
if (UNEXPECTED(seconds < 0)) {
zend_argument_value_error(1, "must be greater than or equal to 0");
RETURN_THROWS();
}
RETURN_LONG(php_sleep((unsigned int)seconds));
}
ZEND_UNREACHABLE();
}
/* }}} */

Expand Down
2 changes: 1 addition & 1 deletion ext/standard/basic_functions.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1966,7 +1966,7 @@ function getopt(string $short_options, array $long_options = [], &$rest_index =

function flush(): void {}

function sleep(int $seconds): int {}
function sleep(int|float $seconds): int {}

function usleep(int $microseconds): void {}

Expand Down
4 changes: 2 additions & 2 deletions ext/standard/basic_functions_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions ext/standard/tests/general_functions/sleep_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
<?php
echo "*** Testing sleep() : basic functionality ***\n";

function have_usleep() {
// if usleep is not avaiable on the native platform,
// usleep() calls will just do nothing
// so to check if we have usleep at runtime, we need to sleep for a short time
$t = microtime(true);
usleep(10000);
return microtime(true) - $t >= 0.009; // 0.009 is 9ms, we asked usleep to sleep for 10ms
}


$sleeptime = 1; // sleep for 1 seconds

set_time_limit(20);
Expand All @@ -31,9 +41,23 @@ if ($time >= $sleeplow) {
} else {
echo "TEST FAILED - time is {$time} secs and sleep was {$sleeptime} secs\n";
}
if(!have_usleep()) {
// ¯\_(ツ)_/¯
echo "FRACTIONAL SLEEP TEST PASSED\n";
} else {
$time = microtime(true);
sleep(0.1);
$time = microtime(true) - $time;
if($time >= 0.09) {
echo "FRACTIONAL SLEEP TEST PASSED\n";
} else {
echo "FRACTIONAL SLEEP TEST FAILED\n";
}
}
?>
--EXPECTF--
*** Testing sleep() : basic functionality ***
Thread slept for %f seconds
Return value: 0
TEST PASSED
FRACTIONAL SLEEP TEST PASSED