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 @@ <testsuites> <testsuite name="Main"> <directory>test</directory> + <directory suffix=".phpt">test</directory> </testsuite> </testsuites> </phpunit> 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-- +<?php + +use Revolt\EventLoop; + +require 'vendor/autoload.php'; + +final class a { + private static self $a; + public static function getInstance(): self { + return self::$a ??= new self; + } + + public function __destruct() + { + echo "Destroying ", self::class, "\n"; + $suspension = EventLoop::getSuspension(); + EventLoop::delay(1.0, $suspension->resume(...)); + $suspension->suspend(); + echo "Finished " . self::class, "\n"; + } +} + +EventLoop::defer(function () { + echo "start\n"; +}); + +a::getInstance(); + +EventLoop::run(); + +?> +--EXPECT-- +start +Destroying a +Finished a