diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 6345e57..0a6176e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -13,6 +13,7 @@ test + test diff --git a/src/EventLoop/Internal/AbstractDriver.php b/src/EventLoop/Internal/AbstractDriver.php index 94de316..998f3b5 100644 --- a/src/EventLoop/Internal/AbstractDriver.php +++ b/src/EventLoop/Internal/AbstractDriver.php @@ -498,9 +498,14 @@ private function invokeCallbacks(): void { while (!$this->microtaskQueue->isEmpty() || !$this->callbackQueue->isEmpty()) { /** @noinspection PhpUnhandledExceptionInspection */ - $yielded = $this->callbackFiber->isStarted() - ? $this->callbackFiber->resume() - : $this->callbackFiber->start(); + if ($this->callbackFiber->isSuspended()) { + $yielded = $this->callbackFiber->resume(); + } else { + if ($this->callbackFiber->isTerminated()) { + $this->createCallbackFiber(); + } + $yielded = $this->callbackFiber->start(); + } if ($yielded !== $this->internalSuspensionMarker) { $this->createCallbackFiber(); diff --git a/test/event_loop_destruction_order.phpt b/test/event_loop_destruction_order.phpt new file mode 100644 index 0000000..0d13794 --- /dev/null +++ b/test/event_loop_destruction_order.phpt @@ -0,0 +1,38 @@ +--TEST-- +Issue #105: Ensure the callback fiber is always alive as long as the event loop lives +--FILE-- +resume(...)); + $suspension->suspend(); + echo "Finished " . self::class, "\n"; + } +} + +EventLoop::defer(function () { + echo "start\n"; +}); + +a::getInstance(); + +EventLoop::run(); + +?> +--EXPECT-- +start +Destroying a +Finished a