Skip to content

Commit 6d45a19

Browse files
committed
Fix reporting refused connections with ExtUvLoop
The underlying `epoll_wait()` reports `EPOLLOUT|EPOLLERR|EPOLLHUP` on the affected file descriptor, which `ext-uv` emits as an error code `EBADF` with no events attached. We explicitly re-enable all active events on this error event to invoke the writable listener for this condition to match other event loop implementations and successfully detect this as a refused connection attempt. All tests are now green.
1 parent 527c60a commit 6d45a19

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

src/ExtUvLoop.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,13 +294,15 @@ private function pollStream($stream)
294294
private function createStreamListener()
295295
{
296296
$callback = function ($event, $status, $events, $stream) {
297-
if (!isset($this->streamEvents[(int) $stream])) {
298-
return;
299-
}
300-
301-
if (($events | 4) === 4) {
302-
// Disconnected
303-
return;
297+
// libuv automatically stops polling on error, re-enable polling to match other loop implementations
298+
if ($status !== 0) {
299+
$this->pollStream($stream);
300+
301+
// libuv may report no events on error, but this should still invoke stream listeners to report closed connections
302+
// re-enable both readable and writable, correct listeners will be checked below anyway
303+
if ($events === 0) {
304+
$events = \UV::READABLE | \UV::WRITABLE;
305+
}
304306
}
305307

306308
if (isset($this->readStreams[(int) $stream]) && ($events & \UV::READABLE)) {

0 commit comments

Comments
 (0)