From e9e227618abd4342dd70fb133f4c535eef9b5458 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Mon, 30 Jan 2017 13:43:28 -0600 Subject: [PATCH 1/3] Require callbacks to be void --- src/Loop.php | 35 ++++++++++++++++++++++++++++------- src/Loop/Driver.php | 30 ++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/Loop.php b/src/Loop.php index 76f54d3..4e6c124 100644 --- a/src/Loop.php +++ b/src/Loop.php @@ -55,11 +55,14 @@ public static function setFactory(DriverFactory $factory = null) /** * Execute a callback within the scope of an event loop driver. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an * exception is thrown that cannot be handled. Exceptions that cannot be handled are exceptions thrown from an * error handler or exceptions that would be passed to an error handler but none exists to handle them. * - * @param callable $callback The callback to execute. + * @param callable(): void $callback The callback to execute. * @param Driver $driver The event loop driver. If `null`, a new one is created from the set factory. * * @return void @@ -136,10 +139,13 @@ public static function stop() /** * Defer the execution of a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The deferred callable MUST be executed in the next tick of the event loop and before any other type of watcher. * Order of enabling MUST be preserved when executing the callbacks. * - * @param callable(string $watcherId, mixed $data) $callback The callback to defer. The `$watcherId` will be + * @param callable(string $watcherId, mixed $data): void $callback The callback to defer. The `$watcherId` will be * invalidated before the callback call. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * @@ -154,11 +160,14 @@ public static function defer(callable $callback, $data = null) /** * Delay the execution of a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which * timers expire first, but timers with the same expiration time MAY be executed in any order. * * @param int $delay The amount of time, in milliseconds, to delay the execution for. - * @param callable(string $watcherId, mixed $data) $callback The callback to delay. The `$watcherId` will be + * @param callable(string $watcherId, mixed $data): void $callback The callback to delay. The `$watcherId` will be * invalidated before the callback call. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * @@ -173,12 +182,15 @@ public static function delay($time, callable $callback, $data = null) /** * Repeatedly execute a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order. * The first execution is scheduled after the first interval period. * * @param int $interval The time interval, in milliseconds, to wait between executions. - * @param callable(string $watcherId, mixed $data) $callback The callback to repeat. + * @param callable(string $watcherId, mixed $data): void $callback The callback to repeat. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -192,6 +204,9 @@ public static function repeat($interval, callable $callback, $data = null) /** * Execute a callback when a stream resource becomes readable or is closed for reading. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid * resources, but are not required to, due to the high performance impact. Watchers on closed resources are @@ -200,7 +215,7 @@ public static function repeat($interval, callable $callback, $data = null) * Multiple watchers on the same stream MAY be executed in any order. * * @param resource $stream The stream to monitor. - * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, resource $stream, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -214,6 +229,9 @@ public static function onReadable($stream, callable $callback, $data = null) /** * Execute a callback when a stream resource becomes writable or is closed for writing. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid * resources, but are not required to, due to the high performance impact. Watchers on closed resources are @@ -222,7 +240,7 @@ public static function onReadable($stream, callable $callback, $data = null) * Multiple watchers on the same stream MAY be executed in any order. * * @param resource $stream The stream to monitor. - * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, resource $stream, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -236,6 +254,9 @@ public static function onWritable($stream, callable $callback, $data = null) /** * Execute a callback when a signal is received. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior. * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical * limitations of the signals being registered globally per process. @@ -243,7 +264,7 @@ public static function onWritable($stream, callable $callback, $data = null) * Multiple watchers on the same signal MAY be executed in any order. * * @param int $signo The signal number to monitor. - * @param callable(string $watcherId, int $signo, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, int $signo, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the $data parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. diff --git a/src/Loop/Driver.php b/src/Loop/Driver.php index 6595ce3..75ad7a6 100644 --- a/src/Loop/Driver.php +++ b/src/Loop/Driver.php @@ -44,10 +44,13 @@ abstract public function stop(); /** * Defer the execution of a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The deferred callable MUST be executed in the next tick of the event loop and before any other type of watcher. * Order of enabling MUST be preserved when executing the callbacks. * - * @param callable(string $watcherId, mixed $data) $callback The callback to defer. The `$watcherId` will be + * @param callable(string $watcherId, mixed $data): void $callback The callback to defer. The `$watcherId` will be * invalidated before the callback call. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * @@ -58,11 +61,14 @@ abstract public function defer(callable $callback, $data = null); /** * Delay the execution of a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which * timers expire first, but timers with the same expiration time MAY be executed in any order. * * @param int $delay The amount of time, in milliseconds, to delay the execution for. - * @param callable(string $watcherId, mixed $data) $callback The callback to delay. The `$watcherId` will be + * @param callable(string $watcherId, mixed $data): void $callback The callback to delay. The `$watcherId` will be * invalidated before the callback call. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * @@ -73,12 +79,15 @@ abstract public function delay($delay, callable $callback, $data = null); /** * Repeatedly execute a callback. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order. * The first execution is scheduled after the first interval period. * * @param int $interval The time interval, in milliseconds, to wait between executions. - * @param callable(string $watcherId, mixed $data) $callback The callback to repeat. + * @param callable(string $watcherId, mixed $data): void $callback The callback to repeat. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -88,6 +97,9 @@ abstract public function repeat($interval, callable $callback, $data = null); /** * Execute a callback when a stream resource becomes readable or is closed for reading. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid * resources, but are not required to, due to the high performance impact. Watchers on closed resources are @@ -96,7 +108,7 @@ abstract public function repeat($interval, callable $callback, $data = null); * Multiple watchers on the same stream MAY be executed in any order. * * @param resource $stream The stream to monitor. - * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, resource $stream, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -106,6 +118,9 @@ abstract public function onReadable($stream, callable $callback, $data = null); /** * Execute a callback when a stream resource becomes writable or is closed for writing. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid * resources, but are not required to, due to the high performance impact. Watchers on closed resources are @@ -114,7 +129,7 @@ abstract public function onReadable($stream, callable $callback, $data = null); * Multiple watchers on the same stream MAY be executed in any order. * * @param resource $stream The stream to monitor. - * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, resource $stream, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. @@ -124,6 +139,9 @@ abstract public function onWritable($stream, callable $callback, $data = null); /** * Execute a callback when a signal is received. * + * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * forwarded to the loop error handler. + * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior. * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical * limitations of the signals being registered globally per process. @@ -131,7 +149,7 @@ abstract public function onWritable($stream, callable $callback, $data = null); * Multiple watchers on the same signal MAY be executed in any order. * * @param int $signo The signal number to monitor. - * @param callable(string $watcherId, int $signo, mixed $data) $callback The callback to execute. + * @param callable(string $watcherId, int $signo, mixed $data): void $callback The callback to execute. * @param mixed $data Arbitrary data given to the callback function as the $data parameter. * * @return string An unique identifier that can be used to cancel, enable or disable the watcher. From b320e7a32e5c8fda1fae7b089b6d435907e5328a Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Tue, 21 Feb 2017 12:02:16 -0600 Subject: [PATCH 2/3] Clarify exception is rethrown if no handler is set --- src/Loop.php | 14 +++++++------- src/Loop/Driver.php | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Loop.php b/src/Loop.php index 14c641c..413fa90 100644 --- a/src/Loop.php +++ b/src/Loop.php @@ -56,7 +56,7 @@ public static function setFactory(DriverFactory $factory = null) * Execute a callback within the scope of an event loop driver. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an * exception is thrown that cannot be handled. Exceptions that cannot be handled are exceptions thrown from an @@ -140,7 +140,7 @@ public static function stop() * Defer the execution of a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be * preserved when executing the callbacks. @@ -164,7 +164,7 @@ public static function defer(callable $callback, $data = null) * Delay the execution of a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which * timers expire first, but timers with the same expiration time MAY be executed in any order. @@ -189,7 +189,7 @@ public static function delay($time, callable $callback, $data = null) * Repeatedly execute a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order. @@ -214,7 +214,7 @@ public static function repeat($interval, callable $callback, $data = null) * Execute a callback when a stream resource becomes readable or is closed for reading. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid @@ -242,7 +242,7 @@ public static function onReadable($stream, callable $callback, $data = null) * Execute a callback when a stream resource becomes writable or is closed for writing. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid @@ -270,7 +270,7 @@ public static function onWritable($stream, callable $callback, $data = null) * Execute a callback when a signal is received. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior. * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical diff --git a/src/Loop/Driver.php b/src/Loop/Driver.php index ab1ac59..129ed0d 100644 --- a/src/Loop/Driver.php +++ b/src/Loop/Driver.php @@ -48,7 +48,7 @@ abstract public function stop(); * Defer the execution of a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be * preserved when executing the callbacks. @@ -68,7 +68,7 @@ abstract public function defer(callable $callback, $data = null); * Delay the execution of a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which * timers expire first, but timers with the same expiration time MAY be executed in any order. @@ -89,7 +89,7 @@ abstract public function delay($delay, callable $callback, $data = null); * Repeatedly execute a callback. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order. @@ -110,7 +110,7 @@ abstract public function repeat($interval, callable $callback, $data = null); * Execute a callback when a stream resource becomes readable or is closed for reading. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid @@ -134,7 +134,7 @@ abstract public function onReadable($stream, callable $callback, $data = null); * Execute a callback when a stream resource becomes writable or is closed for writing. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid @@ -158,7 +158,7 @@ abstract public function onWritable($stream, callable $callback, $data = null); * Execute a callback when a signal is received. * * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be - * forwarded to the loop error handler. + * forwarded to the loop error handler or thrown if none exists. * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior. * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical From e7ef8e9eff49debbb1923ae99cd52214d4bde731 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Tue, 21 Feb 2017 12:16:03 -0600 Subject: [PATCH 3/3] =?UTF-8?q?SHOULD=20=E2=86=92=20MUST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Loop.php | 14 +++++++------- src/Loop/Driver.php | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Loop.php b/src/Loop.php index 413fa90..aa47e6f 100644 --- a/src/Loop.php +++ b/src/Loop.php @@ -55,7 +55,7 @@ public static function setFactory(DriverFactory $factory = null) /** * Execute a callback within the scope of an event loop driver. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an @@ -139,7 +139,7 @@ public static function stop() /** * Defer the execution of a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be @@ -163,7 +163,7 @@ public static function defer(callable $callback, $data = null) /** * Delay the execution of a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which @@ -188,7 +188,7 @@ public static function delay($time, callable $callback, $data = null) /** * Repeatedly execute a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be @@ -213,7 +213,7 @@ public static function repeat($interval, callable $callback, $data = null) /** * Execute a callback when a stream resource becomes readable or is closed for reading. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the @@ -241,7 +241,7 @@ public static function onReadable($stream, callable $callback, $data = null) /** * Execute a callback when a stream resource becomes writable or is closed for writing. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the @@ -269,7 +269,7 @@ public static function onWritable($stream, callable $callback, $data = null) /** * Execute a callback when a signal is received. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior. diff --git a/src/Loop/Driver.php b/src/Loop/Driver.php index 129ed0d..437cf15 100644 --- a/src/Loop/Driver.php +++ b/src/Loop/Driver.php @@ -47,7 +47,7 @@ abstract public function stop(); /** * Defer the execution of a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be @@ -67,7 +67,7 @@ abstract public function defer(callable $callback, $data = null); /** * Delay the execution of a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which @@ -88,7 +88,7 @@ abstract public function delay($delay, callable $callback, $data = null); /** * Repeatedly execute a callback. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be @@ -109,7 +109,7 @@ abstract public function repeat($interval, callable $callback, $data = null); /** * Execute a callback when a stream resource becomes readable or is closed for reading. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the @@ -133,7 +133,7 @@ abstract public function onReadable($stream, callable $callback, $data = null); /** * Execute a callback when a stream resource becomes writable or is closed for writing. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the @@ -157,7 +157,7 @@ abstract public function onWritable($stream, callable $callback, $data = null); /** * Execute a callback when a signal is received. * - * If the callback is not a void function (does not return null), an implementation-specific exception SHOULD be + * If the callback is not a void function (does not return null), an implementation-specific exception MUST be * forwarded to the loop error handler or thrown if none exists. * * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior.