From 99fe17a506166a202831bf39093a20bbfc95baa2 Mon Sep 17 00:00:00 2001 From: xjaja <5057757+xjaja@users.noreply.github.com> Date: Fri, 24 Feb 2023 04:04:15 +0800 Subject: [PATCH 1/3] Fix Fiber leaks if Suspension never resumed --- src/EventLoop/Internal/AbstractDriver.php | 11 ++++++++++- test/EventLoopTest.php | 3 +-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/EventLoop/Internal/AbstractDriver.php b/src/EventLoop/Internal/AbstractDriver.php index 78578bd..35639f4 100644 --- a/src/EventLoop/Internal/AbstractDriver.php +++ b/src/EventLoop/Internal/AbstractDriver.php @@ -285,12 +285,21 @@ public function getSuspension(): Suspension \assert($fiber !== $this->fiber); // Use current object in case of {main} - return $this->suspensions[$fiber ?? $this] ??= new DriverSuspension( + if (isset($this->suspensions[$fiber ?? $this])) { + if ($suspension = $this->suspensions[$fiber ?? $this]->get()) { + return $suspension; + } + } + + $suspension = new DriverSuspension( $this->runCallback, $this->queueCallback, $this->interruptCallback, $this->suspensions ); + $this->suspensions[$fiber ?? $this] = \WeakReference::create($suspension); + + return $suspension; } public function setErrorHandler(?\Closure $errorHandler): void diff --git a/test/EventLoopTest.php b/test/EventLoopTest.php index 9420b9f..0fb1ab2 100644 --- a/test/EventLoopTest.php +++ b/test/EventLoopTest.php @@ -269,8 +269,7 @@ public function testSuspensionWithinCallbackGarbageCollectionSuspended(): void \gc_collect_cycles(); - // This documents an expected failure, should actually be true, but suspensions have to be resumed currently. - self::assertNull($finally); + self::assertTrue($finally); } public function testSuspensionWithinQueue(): void From f31a178d99ae5b7bd35de9d8bf537654530759f7 Mon Sep 17 00:00:00 2001 From: xjaja <5057757+xjaja@users.noreply.github.com> Date: Sat, 25 Feb 2023 19:56:55 +0800 Subject: [PATCH 2/3] Update DriverSuspension.php --- src/EventLoop/Internal/DriverSuspension.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/EventLoop/Internal/DriverSuspension.php b/src/EventLoop/Internal/DriverSuspension.php index a1d9778..74250d5 100644 --- a/src/EventLoop/Internal/DriverSuspension.php +++ b/src/EventLoop/Internal/DriverSuspension.php @@ -104,17 +104,17 @@ public function suspend(): mixed $info = ''; $suspensions = $this->suspensions->get(); if ($suspensions) { - \gc_collect_cycles(); - - /** @var self $suspension */ - foreach ($suspensions as $suspension) { - $fiber = $suspension->fiberRef?->get(); - if ($fiber === null) { - continue; + foreach ($suspensions as $suspensionRef) { + /** @var self $suspension */ + if ($suspension = $suspensionRef->get()) { + $fiber = $suspension->fiberRef?->get(); + if ($fiber === null) { + continue; + } + + $reflectionFiber = new \ReflectionFiber($fiber); + $info .= "\n\n" . $this->formatStacktrace($reflectionFiber->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); } - - $reflectionFiber = new \ReflectionFiber($fiber); - $info .= "\n\n" . $this->formatStacktrace($reflectionFiber->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); } } From e6f28bf9e3b0ab65a8650ac632e753907369c3d6 Mon Sep 17 00:00:00 2001 From: xjaja <5057757+xjaja@users.noreply.github.com> Date: Sat, 25 Feb 2023 20:01:05 +0800 Subject: [PATCH 3/3] Update DriverSuspension.php --- src/EventLoop/Internal/DriverSuspension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventLoop/Internal/DriverSuspension.php b/src/EventLoop/Internal/DriverSuspension.php index 74250d5..a598360 100644 --- a/src/EventLoop/Internal/DriverSuspension.php +++ b/src/EventLoop/Internal/DriverSuspension.php @@ -111,7 +111,7 @@ public function suspend(): mixed if ($fiber === null) { continue; } - + $reflectionFiber = new \ReflectionFiber($fiber); $info .= "\n\n" . $this->formatStacktrace($reflectionFiber->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); }