Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
38 changes: 38 additions & 0 deletions ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
Poll stream - socket read/write events with maxEvents equal to the FD count
--FILE--
<?php
require_once __DIR__ . '/poll.inc';

$poll_ctx = pt_new_stream_poll();

// Each FD is ready for both read and write. Backends that report read and
// write separately (kqueue) see twice as many events as FDs and have to merge
// them without dropping any FD, filling only half of the maxEvents entries.
$writers = [];
$expected = [];
for ($i = 0; $i < 4; $i++) {
list($reader, $writer) = pt_new_socket_pair();
$writers[$i] = $writer;
pt_stream_poll_add($poll_ctx, $reader, [Io\Poll\Event::Read, Io\Poll\Event::Write], "sock$i");
pt_write_sleep($writer, "test $i data");
$expected[] = [
'events' => [Io\Poll\Event::Read, Io\Poll\Event::Write],
'data' => "sock$i",
'read' => "test $i data",
];
}

pt_expect_events($poll_ctx->wait(0, 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);

?>
--EXPECT--
Events matched - count: 4
Events matched - count: 4
45 changes: 45 additions & 0 deletions ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
--TEST--
Poll stream - TCP read with maxEvents smaller than the number of ready FDs
--FILE--
<?php
require_once __DIR__ . '/poll.inc';

list($clients, $servers) = pt_new_tcp_socket_connections(8);
$poll_ctx = pt_new_stream_poll();

for ($i = 0; $i < count($servers); $i++) {
pt_stream_poll_add($poll_ctx, $servers[$i], [Io\Poll\Event::Read], "server$i");
}

for ($i = 0; $i < count($clients); $i++) {
pt_write_sleep($clients[$i], "test $i data");
}

// 8 FDs are ready but only 4 events fit into the buffer, so the remaining
// 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);
echo "Round $round count: " . count($watchers) . "\n";
foreach ($watchers as $watcher) {
$data = $watcher->getData();
if (isset($seen[$data])) {
echo "Duplicate event for $data\n";
}
$seen[$data] = true;
// Drain so level triggering does not re-report the FD
fread($watcher->getHandle()->getStream(), 1024);
}
}

ksort($seen);
echo "Seen: " . implode(',', array_keys($seen)) . "\n";

pt_expect_events($poll_ctx->wait(0), []);

?>
--EXPECT--
Round 1 count: 4
Round 2 count: 4
Seen: server0,server1,server2,server3,server4,server5,server6,server7
Events matched - count: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
Poll stream - TCP read oneshot with maxEvents smaller than the number of ready FDs
--FILE--
<?php
require_once __DIR__ . '/poll.inc';

list($clients, $servers) = pt_new_tcp_socket_connections(8);
$poll_ctx = pt_new_stream_poll();

for ($i = 0; $i < count($servers); $i++) {
pt_stream_poll_add($poll_ctx, $servers[$i], [Io\Poll\Event::Read, Io\Poll\Event::OneShot], "server$i");
}

for ($i = 0; $i < count($clients); $i++) {
pt_write_sleep($clients[$i], "test $i data");
}

// 8 oneshot FDs are ready but only 4 events fit into the buffer. The events
// that did not fit must not be consumed - the following wait() has to deliver
// them, and each oneshot event must be delivered exactly once.
$seen = [];
for ($round = 1; $round <= 2; $round++) {
$watchers = $poll_ctx->wait(0, 100000, 4);
echo "Round $round count: " . count($watchers) . "\n";
foreach ($watchers as $watcher) {
$data = $watcher->getData();
if (isset($seen[$data])) {
echo "Duplicate event for $data\n";
}
$seen[$data] = true;
}
}

ksort($seen);
echo "Seen: " . implode(',', array_keys($seen)) . "\n";

// 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), []);

?>
--EXPECT--
Round 1 count: 4
Round 2 count: 4
Seen: server0,server1,server2,server3,server4,server5,server6,server7
Events matched - count: 0
Loading
Loading