From 2372142f77a4fee7e35b729d08a8585521d6cbd4 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Fri, 1 May 2020 14:44:34 -0500 Subject: [PATCH] Set/restore error handler within each loop iteration --- lib/ResourceOutputStream.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/ResourceOutputStream.php b/lib/ResourceOutputStream.php index f10f1a5..b26aceb 100644 --- a/lib/ResourceOutputStream.php +++ b/lib/ResourceOutputStream.php @@ -62,13 +62,6 @@ public function __construct($stream, int $chunkSize = null) $this->watcher = Loop::onWritable($stream, static function ($watcher, $stream) use ($writes, &$chunkSize, &$writable, &$resource) { $firstWrite = true; - // Using error handler to verify that a write of zero bytes was not due an error. - // @see https://github.com/reactphp/stream/pull/150 - $error = 0; - \set_error_handler(static function (int $errno) use (&$error) { - $error = $errno; - }); - try { while (!$writes->isEmpty()) { /** @var Deferred $deferred */ @@ -84,6 +77,13 @@ public function __construct($stream, int $chunkSize = null) throw new ClosedException("The stream was closed by the peer"); } + // Using error handler to verify that a write of zero bytes was not due an error. + // @see https://github.com/reactphp/stream/pull/150 + $error = 0; + \set_error_handler(static function (int $errno) use (&$error) { + $error = $errno; + }); + // Error reporting suppressed since fwrite() emits E_WARNING if the pipe is broken or the buffer is full. // Use conditional, because PHP doesn't like getting null passed if ($chunkSize) { @@ -92,6 +92,8 @@ public function __construct($stream, int $chunkSize = null) $written = @\fwrite($stream, $data); } + \restore_error_handler(); + \assert( $written !== false || \PHP_VERSION_ID >= 70400, // PHP 7.4+ returns false on EPIPE. "Trying to write on a previously fclose()'d resource. Do NOT manually fclose() resources the still referenced in the loop." @@ -144,8 +146,6 @@ public function __construct($stream, int $chunkSize = null) if ($writes->isEmpty()) { Loop::disable($watcher); } - - \restore_error_handler(); } });