/** * Execute a callback when a stream resource becomes readable. * Returned Generators are run as coroutines. Failures of the coroutine are forwarded to the loop error handler. * * @see \Interop\Async\Loop::onReadable() * * @param resource $stream The stream to monitor. * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute. * @param mixed $data * * @return string Watcher identifier. */ function onReadable($stream, callable $callback, $data = null) : string { return Loop::onReadable($stream, function ($watcherId, $stream, $data) use($callback) { $result = $callback($watcherId, $stream, $data); if ($result instanceof \Generator) { rethrow(new Coroutine($result)); return; } }, $data); }