Commit ed2ffe6f70f for php.net

commit ed2ffe6f70f6d7f8391f46b1fac88b60b97cdb6b
Author: Tim Düsterhus <tim@bastelstu.be>
Date:   Fri Aug 7 12:48:41 2026 +0200

    standard: Take `Time\Duration` in `Io\Poll\Context::wait()` (#23092)

    RFC: https://wiki.php.net/rfc/duration_class

diff --git a/NEWS b/NEWS
index 890c5d89039..b99bdc51e87 100644
--- a/NEWS
+++ b/NEWS
@@ -67,6 +67,8 @@ PHP                                                                        NEWS
     is_link(), file_exists(), lstat(), stat(). (Girgias)
   . Fixed bug GH-22818 (stream_filter_register() orphaned user_filter_map on
     shutdown re-registration). (David Carlier)
+  . Io\Poll\Context::wait() now takes a Time\Duration object as a timeout.
+    (timwolla)

 30 Jul 2026, PHP 8.6.0alpha3

diff --git a/ext/standard/io_poll.c b/ext/standard/io_poll.c
index ca363c7b37d..c29ccfee04f 100644
--- a/ext/standard/io_poll.c
+++ b/ext/standard/io_poll.c
@@ -19,6 +19,7 @@
 #include "php_poll.h"
 #include "io_poll_arginfo.h"
 #include "io_poll_decl.h"
+#include "ext/date/php_time.h"

 /* Class entries */
 static zend_class_entry *php_io_poll_backend_class_entry;
@@ -774,38 +775,28 @@ PHP_METHOD(Io_Poll_Context, add)

 PHP_METHOD(Io_Poll_Context, wait)
 {
-	zend_long timeout_seconds = -1;
-	bool timeout_seconds_is_null = true;
-	zend_long timeout_microseconds = 0;
+	php_date_time_duration *timeout = NULL;
 	zend_long max_events = 0;
 	bool max_events_is_null = true;

-	ZEND_PARSE_PARAMETERS_START(0, 3)
+	ZEND_PARSE_PARAMETERS_START(0, 2)
 		Z_PARAM_OPTIONAL
-		Z_PARAM_LONG_OR_NULL(timeout_seconds, timeout_seconds_is_null)
-		Z_PARAM_LONG(timeout_microseconds)
+		Z_PARAM_DATE_TIME_DURATION_OR_NULL(timeout)
 		Z_PARAM_LONG_OR_NULL(max_events, max_events_is_null)
 	ZEND_PARSE_PARAMETERS_END();

 	php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis());

-	/* Build timespec from seconds + microseconds, or NULL for indefinite */
-	struct timespec ts;
-	const struct timespec *timeout = NULL;
-	if (timeout_seconds >= 0) {
-		if (timeout_microseconds < 0) {
-			zend_argument_value_error(2, "must be greater than or equal to 0");
+	/* Build timespec from php_date_time_duration, or NULL for indefinite */
+	struct timespec timeout_ts;
+	if (timeout) {
+		if (timeout->duration.negative) {
+			zend_argument_value_error(2, "must not be negative");
 			RETURN_THROWS();
 		}

-		/* Allow microseconds >= 1000000, carry overflow into seconds
-		 * (same behavior as stream_select) */
-		ts.tv_sec = (time_t) (timeout_seconds + (timeout_microseconds / 1000000));
-		ts.tv_nsec = (long) ((timeout_microseconds % 1000000) * 1000);
-		timeout = &ts;
-	} else if (!timeout_seconds_is_null) {
-		zend_argument_value_error(1, "must be greater than or equal to 0");
-		RETURN_THROWS();
+		timeout_ts.tv_sec = timeout->duration.seconds;
+		timeout_ts.tv_nsec = timeout->duration.nanoseconds;
 	}

 	if (max_events_is_null) {
@@ -814,12 +805,12 @@ PHP_METHOD(Io_Poll_Context, wait)
 			max_events = 64;
 		}
 	} else if (max_events <= 0) {
-		zend_argument_value_error(3, "must be greater than 0");
+		zend_argument_value_error(2, "must be greater than 0");
 		RETURN_THROWS();
 	}

 	php_poll_event *events = safe_emalloc(max_events, sizeof(*events), 0);
-	int num_events = php_poll_wait(intern->ctx, events, (int) max_events, timeout);
+	int num_events = php_poll_wait(intern->ctx, events, (int) max_events, timeout ? &timeout_ts : NULL);

 	if (num_events < 0) {
 		php_poll_error err = php_poll_get_error(intern->ctx);
diff --git a/ext/standard/io_poll.stub.php b/ext/standard/io_poll.stub.php
index 83c1ba5cbe2..e3bcbf11c87 100644
--- a/ext/standard/io_poll.stub.php
+++ b/ext/standard/io_poll.stub.php
@@ -86,7 +86,7 @@ public function __construct(Backend $backend = Backend::Auto) {}
         public function add(Handle $handle, array $events, mixed $data = null): Watcher {}

         /** @return list<Watcher> */
-        public function wait(?int $timeoutSeconds = null, int $timeoutMicroseconds = 0, ?int $maxEvents = null): array {}
+        public function wait(?\Time\Duration $timeout = null, ?int $maxEvents = null): array {}

         public function getBackend(): Backend {}
     }
diff --git a/ext/standard/io_poll_arginfo.h b/ext/standard/io_poll_arginfo.h
index 5fc62f62956..801df235c26 100644
Binary files a/ext/standard/io_poll_arginfo.h and b/ext/standard/io_poll_arginfo.h differ
diff --git a/ext/standard/io_poll_decl.h b/ext/standard/io_poll_decl.h
index 2b09e3665f5..de49880392a 100644
Binary files a/ext/standard/io_poll_decl.h and b/ext/standard/io_poll_decl.h differ
diff --git a/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
index 4f32ec28c88..3e64d950c19 100644
--- a/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
@@ -10,7 +10,7 @@
 $watcher = pt_stream_poll_add($poll_ctx, $socket2, [Io\Poll\Event::Write], "socket_data");
 $watcher->modify([Io\Poll\Event::Write], "modified_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'modified_data']
 ]);
 ?>
diff --git a/ext/standard/tests/poll/poll_stream_sock_read.phpt b/ext/standard/tests/poll/poll_stream_sock_read.phpt
index 70aebc9cd92..0b44a3d14ea 100644
--- a/ext/standard/tests/poll/poll_stream_sock_read.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_read.phpt
@@ -10,7 +10,7 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket_data");

 fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data']
 ]);

diff --git a/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
index c5fec539165..2662a4e1f4c 100644
--- a/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
@@ -11,14 +11,14 @@
 $watcher1w = pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket_data_1");
 pt_stream_poll_add($poll_ctx, $socket2w, [Io\Poll\Event::Write], "socket_data_2");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_1'],
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2']
 ]);

 $watcher1w->remove();

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2']
 ]);

diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
index 3909dea5863..f81ac40bcfa 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
@@ -13,7 +13,7 @@
 fwrite($socket1w, "test data");

 fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     [
         'events' => [
             'default' => [Io\Poll\Event::Write, Io\Poll\Event::Error, Io\Poll\Event::HangUp],
@@ -28,7 +28,7 @@
 ], $poll_ctx);

 fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
index d78d3f4fde3..c7374d2986e 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
@@ -23,14 +23,14 @@
     ];
 }

-pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 8), $expected);

 // All read data was drained above, so only write events remain
 $expected = [];
 for ($i = 0; $i < 4; $i++) {
     $expected[] = ['events' => [Io\Poll\Event::Write], 'data' => "sock$i"];
 }
-pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 8), $expected);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
index f25cb973ddc..63b22bd9494 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
@@ -15,32 +15,32 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read, Io\Poll\Event::EdgeTriggered], "socket1_data");
 pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write, Io\Poll\Event::EdgeTriggered], "socket2_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
 ]);

-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);

 fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
 ]);

 fwrite($socket1w, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
 ]);

-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 fwrite($socket1w, " and even more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data']
 ]);

 fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     [
         'events' => ['default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp]],
         'data' => 'socket2_data'
@@ -48,7 +48,7 @@
 ], $poll_ctx);

 fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
index 8bc8ea7fcc3..63942087261 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
@@ -10,39 +10,39 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket1_data");
 pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket2_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
 ]);

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
 ]);

 fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
 ]);

 fwrite($socket1w, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
 ]);

-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
 ]);

 fwrite($socket1w, " and even more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data']
 ]);

 fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     [
         'events' => [
             'default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp],
@@ -56,7 +56,7 @@
 ], $poll_ctx);

 fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
index 4a7b67b8243..29432b7f95a 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
@@ -15,11 +15,11 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read, Io\Poll\Event::EdgeTriggered], "socket1_data");
 pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write, Io\Poll\Event::EdgeTriggered], "socket2_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
 ]);
 fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
 ]);

diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
index a807e573c5f..f0a64fc0638 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
@@ -10,11 +10,11 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket1_data");
 pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket2_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
 ]);
 fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
 ]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_write.phpt b/ext/standard/tests/poll/poll_stream_sock_write.phpt
index 2d937d7e9a3..1bfb0524ec8 100644
--- a/ext/standard/tests/poll/poll_stream_sock_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_write.phpt
@@ -9,7 +9,7 @@

 pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket_data");

-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data']
 ]);

diff --git a/ext/standard/tests/poll/poll_stream_sock_write_close.phpt b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
index 8927e017b05..49e452907f2 100644
--- a/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
@@ -13,7 +13,7 @@

 fclose($socket1w);
 fclose($socket2w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read.phpt b/ext/standard/tests/poll/poll_stream_tcp_read.phpt
index 71c7af0ca73..e9296a266e0 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read.phpt
@@ -10,7 +10,7 @@
 pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket_data");

 pt_write_sleep($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data']
 ]);

diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
index f927e73ed4d..bb2c734cbf2 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
@@ -19,7 +19,7 @@
 // events must be delivered by the following wait() without any duplicates.
 $seen = [];
 for ($round = 1; $round <= 2; $round++) {
-    $watchers = $poll_ctx->wait(0, 100000, 4);
+    $watchers = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 4);
     echo "Round $round count: " . count($watchers) . "\n";
     foreach ($watchers as $watcher) {
         $data = $watcher->getData();
@@ -35,7 +35,7 @@
 ksort($seen);
 echo "Seen: " . implode(',', array_keys($seen)) . "\n";

-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
index db2ff71fb7c..bc49571ca8e 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
@@ -11,7 +11,7 @@
     pt_stream_poll_add($poll_ctx, $servers[$i], [Io\Poll\Event::Read], "server{$i}_data");
 }

-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);

 for ($i = 0; $i < count($clients); $i++) {
     pt_write_sleep($clients[$i], "test $i data");
@@ -22,16 +22,16 @@
 for ($i = 0; $i < 20; $i++) {
     $expected_events[] = ['events' => [Io\Poll\Event::Read], 'data' => "server{$i}_data", 'read' => "test $i data"];
 }
-pt_expect_events($poll_ctx->wait(0, 100000), $expected_events);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), $expected_events);

 pt_write_sleep($clients[1], "more data");
 pt_write_sleep($clients[2], "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'more data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'more data']
 ]);

-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
index 02db6355ca1..c8f7c424b3d 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
@@ -13,18 +13,18 @@
 pt_stream_poll_add($poll_ctx, $client2, [Io\Poll\Event::Read, Io\Poll\Event::OneShot], "client2_data");
 pt_stream_poll_add($poll_ctx, $server2, [Io\Poll\Event::Read, Io\Poll\Event::OneShot], "server2_data");

-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);

 pt_write_sleep($client1, "test data");
 pt_write_sleep($client2, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'test data'],
     ['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'test data']
 ]);

 pt_write_sleep($client1, "more data");
 pt_write_sleep($client2, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
index d7a2e48be6f..73142b16f63 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
@@ -20,7 +20,7 @@
 // them, and each oneshot event must be delivered exactly once.
 $seen = [];
 for ($round = 1; $round <= 2; $round++) {
-    $watchers = $poll_ctx->wait(0, 100000, 4);
+    $watchers = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 4);
     echo "Round $round count: " . count($watchers) . "\n";
     foreach ($watchers as $watcher) {
         $data = $watcher->getData();
@@ -36,7 +36,7 @@

 // Every oneshot watcher fired once, so new data must not be reported
 pt_write_sleep($clients[0], "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
index 6132975e1b5..79db5608b97 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
@@ -10,16 +10,16 @@
 pt_stream_poll_add($poll_ctx, $client, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "client_data");
 pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "server_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
     ['events' => [Io\Poll\Event::Write], 'data' => 'server_data']
 ]);

 pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
index c480caf1b73..b8646f252e7 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
@@ -11,13 +11,13 @@
 pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "server_data");

 pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
     ['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data']
 ]);

 pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);

 ?>
 --EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
index f29a74f19ed..9300e2266f3 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
@@ -10,14 +10,14 @@
 pt_stream_poll_add($poll_ctx, $client, [Io\Poll\Event::Read, Io\Poll\Event::Write], "client_data");
 pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write], "server_data");

-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
     ['events' => [Io\Poll\Event::Write], 'data' => 'server_data']
 ]);

 fwrite($client, "test data");
 usleep(10000);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
     ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
     ['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data', 'read' => 'test data']
 ]);
diff --git a/ext/standard/tests/poll/poll_stream_wait_no_add.phpt b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
index a297fa5e116..14789d709f6 100644
--- a/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
+++ b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
@@ -4,7 +4,7 @@
 <?php
 require_once __DIR__ . '/poll.inc';
 $poll_ctx = pt_new_stream_poll();
-$events = $poll_ctx->wait(0, 100000);
+$events = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000));
 pt_print_events($events);

 ?>