function StreamSelectDriver::selectStreams
Parameters
array<int, resource> $read:
array<int, resource> $write:
1 call to StreamSelectDriver::selectStreams()
- StreamSelectDriver::dispatch in vendor/
revolt/ event-loop/ src/ EventLoop/ Driver/ StreamSelectDriver.php
File
-
vendor/
revolt/ event-loop/ src/ EventLoop/ Driver/ StreamSelectDriver.php, line 231
Class
Namespace
Revolt\EventLoop\DriverCode
private function selectStreams(array $read, array $write, float $timeout) : void {
if (!empty($read) || !empty($write)) {
// Use stream_select() if there are any streams in the loop.
if ($timeout >= 0) {
$seconds = (int) $timeout;
$microseconds = (int) (($timeout - $seconds) * 1000000);
}
else {
$seconds = null;
$microseconds = null;
}
// Failed connection attempts are indicated via except on Windows
// @link https://github.com/reactphp/event-loop/blob/8bd064ce23c26c4decf186c2a5a818c9a8209eb0/src/StreamSelectLoop.php#L279-L287
// @link https://docs.microsoft.com/de-de/windows/win32/api/winsock2/nf-winsock2-select
$except = null;
if (\DIRECTORY_SEPARATOR === '\\') {
$except = $write;
}
\set_error_handler($this->streamSelectErrorHandler);
try {
/** @psalm-suppress InvalidArgument */
$result = \stream_select($read, $write, $except, $seconds, $microseconds);
} finally {
\restore_error_handler();
}
if ($this->streamSelectIgnoreResult || $result === 0) {
$this->streamSelectIgnoreResult = false;
return;
}
if (!$result) {
throw new \Exception('Unknown error during stream_select');
}
foreach ($read as $stream) {
$streamId = (int) $stream;
if (!isset($this->readCallbacks[$streamId])) {
continue;
// All read callbacks disabled.
}
foreach ($this->readCallbacks[$streamId] as $callback) {
$this->enqueueCallback($callback);
}
}
/** @var array<int, resource>|null $except */
if ($except) {
foreach ($except as $key => $socket) {
$write[$key] = $socket;
}
}
foreach ($write as $stream) {
$streamId = (int) $stream;
if (!isset($this->writeCallbacks[$streamId])) {
continue;
// All write callbacks disabled.
}
foreach ($this->writeCallbacks[$streamId] as $callback) {
$this->enqueueCallback($callback);
}
}
return;
}
if ($timeout < 0) {
// Only signal callbacks are enabled, so sleep indefinitely.
/** @psalm-suppress ArgumentTypeCoercion */
\usleep(\PHP_INT_MAX);
return;
}
if ($timeout > 0) {
// Sleep until next timer expires.
/** @psalm-suppress ArgumentTypeCoercion $timeout is positive here. */
\usleep((int) ($timeout * 1000000));
}
}