Skip to content

Commit 2c3af8e

Browse files
committed
Sync sleep API to the latest PHP version, fix and test
1 parent cdee6d5 commit 2c3af8e

File tree

2 files changed

+47
-34
lines changed

2 files changed

+47
-34
lines changed

‎ext-src/swoole_runtime.cc‎

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,12 +1815,14 @@ static PHP_METHOD(swoole_runtime, setHookFlags) {
18151815

18161816
static PHP_FUNCTION(swoole_sleep) {
18171817
zend_long num;
1818-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num) == FAILURE) {
1819-
RETURN_FALSE;
1820-
}
1818+
1819+
ZEND_PARSE_PARAMETERS_START(1, 1)
1820+
Z_PARAM_LONG(num)
1821+
ZEND_PARSE_PARAMETERS_END();
1822+
18211823
if (num < 0) {
1822-
php_error_docref(nullptr, E_WARNING, "Number of seconds must be greater than or equal to 0");
1823-
RETURN_FALSE;
1824+
zend_argument_value_error(1, "must be greater than or equal to 0");
1825+
RETURN_THROWS();
18241826
}
18251827

18261828
if (Coroutine::get_current()) {
@@ -1838,9 +1840,10 @@ static PHP_FUNCTION(swoole_usleep) {
18381840
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
18391841

18401842
if (num < 0) {
1841-
php_error_docref(nullptr, E_WARNING, "Number of seconds must be greater than or equal to 0");
1842-
RETURN_FALSE;
1843+
zend_argument_value_error(1, "must be greater than or equal to 0");
1844+
RETURN_THROWS();
18431845
}
1846+
18441847
double sec = (double) num / 1000000;
18451848
if (Coroutine::get_current()) {
18461849
System::sleep(sec);
@@ -1857,14 +1860,15 @@ static PHP_FUNCTION(swoole_time_nanosleep) {
18571860
Z_PARAM_LONG(tv_nsec)
18581861
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
18591862

1860-
if (tv_sec < 0) {
1861-
php_error_docref(nullptr, E_WARNING, "The seconds value must be greater than 0");
1862-
RETURN_FALSE;
1863-
}
1864-
if (tv_nsec < 0) {
1865-
php_error_docref(nullptr, E_WARNING, "The nanoseconds value must be greater than 0");
1866-
RETURN_FALSE;
1867-
}
1863+
if (tv_sec < 0) {
1864+
zend_argument_value_error(1, "must be greater than or equal to 0");
1865+
RETURN_THROWS();
1866+
}
1867+
if (tv_nsec < 0) {
1868+
zend_argument_value_error(2, "must be greater than or equal to 0");
1869+
RETURN_THROWS();
1870+
}
1871+
18681872
double _time = (double) tv_sec + (double) tv_nsec / 1000000000.00;
18691873
if (Coroutine::get_current()) {
18701874
System::sleep(_time);
@@ -1887,27 +1891,29 @@ static PHP_FUNCTION(swoole_time_nanosleep) {
18871891
}
18881892

18891893
static PHP_FUNCTION(swoole_time_sleep_until) {
1890-
double d_ts;
1894+
double target_secs;
1895+
const uint64_t ns_per_sec = 1000000000;
1896+
const double top_target_sec = (double)(UINT64_MAX / ns_per_sec);
18911897

18921898
ZEND_PARSE_PARAMETERS_START(1, 1)
1893-
Z_PARAM_DOUBLE(d_ts)
1899+
Z_PARAM_DOUBLE(target_secs)
18941900
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
18951901

1896-
if (!std::isfinite(d_ts) || d_ts < 0) {
1897-
php_error_docref(nullptr, E_WARNING, "Invalid timestamp: must be a positive finite number");
1898-
RETURN_FALSE;
1899-
}
1902+
if (UNEXPECTED(!(target_secs >= 0 && target_secs <= top_target_sec))) {
1903+
zend_argument_value_error(1, "must be between 0 and %" PRIu64, (uint64_t)top_target_sec);
1904+
RETURN_THROWS();
1905+
}
19001906

19011907
using namespace std::chrono;
19021908
using dseconds = duration<double>;
19031909

19041910
const auto now = system_clock::now();
1905-
const auto target_duration = duration_cast<system_clock::duration>(dseconds(d_ts));
1911+
const auto target_duration = duration_cast<system_clock::duration>(dseconds(target_secs));
19061912
const auto target_time = system_clock::time_point(target_duration);
19071913

19081914
if (target_time <= now) {
1909-
php_error_docref(NULL, E_WARNING, "Argument #1 ($timestamp) must be greater than or equal to the current time");
1910-
RETURN_FALSE;
1915+
php_error_docref(NULL, E_WARNING, "Argument #1 ($timestamp) must be greater than or equal to the current time");
1916+
RETURN_FALSE;
19111917
}
19121918

19131919
const auto sleep_duration = target_time - now;

‎tests/swoole_runtime/sleep.phpt‎

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,31 @@ go(function () {
1212
Assert::eq(sleep(1), 0);
1313
time_approximate(1, microtime(true) - $s);
1414
Assert::eq(sleep(0), 0);
15-
Assert::false(sleep(-1), -1);
15+
try {
16+
sleep(-1);
17+
} catch (Throwable $e) {
18+
Assert::contains($e->getMessage(), 'must be greater than or equal to 0');
19+
}
1620

1721
// usleep
1822
$s = microtime(true);
1923
$t = ms_random(0.01, 0.1);
2024
usleep($t * 1000 * 1000);
2125
time_approximate($t, microtime(true) - $s);
2226
usleep(0);
23-
usleep(-1);
27+
try {
28+
usleep(-1);
29+
} catch (Throwable $e) {
30+
Assert::contains($e->getMessage(), 'must be greater than or equal to 0');
31+
}
2432

2533
// time_nanosleep
26-
Assert::false(time_nanosleep(-1, 1));
34+
try {
35+
time_nanosleep(-1, 1);
36+
} catch (Throwable $e) {
37+
Assert::contains($e->getMessage(), 'must be greater than or equal to 0');
38+
}
39+
2740
Assert::true(time_nanosleep(0, 1));
2841
Assert::true(time_nanosleep(0, 1000 * 1000));
2942

@@ -40,12 +53,6 @@ echo "\nDONE\n";
4053
--EXPECTF--
4154
NON-BLOCKED
4255

43-
Warning: sleep(): Number of seconds must be greater than or equal to 0 in %s on line %d
44-
45-
Warning: usleep(): Number of seconds must be greater than or equal to 0 in %s on line %d
46-
47-
Warning: time_nanosleep(): The seconds value must be greater than 0 in %s on line %d
48-
49-
Warning: time_sleep_until(): Sleep until to time is less than current time in %s on line %d
56+
Warning: time_sleep_until(): Argument #1 ($timestamp) must be greater than or equal to the current time in %s on line %d
5057

5158
DONE

0 commit comments

Comments
 (0)