Skip to content

Commit d4ab0bc

Browse files
committed
Fix #105: Ensure the callback fiber is always alive as long as the event loop lives
1 parent 09bf1bf commit d4ab0bc

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<testsuites>
1414
<testsuite name="Main">
1515
<directory>test</directory>
16+
<directory suffix=".phpt">test</directory>
1617
</testsuite>
1718
</testsuites>
1819
</phpunit>

src/EventLoop/Internal/AbstractDriver.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,14 @@ private function invokeCallbacks(): void
498498
{
499499
while (!$this->microtaskQueue->isEmpty() || !$this->callbackQueue->isEmpty()) {
500500
/** @noinspection PhpUnhandledExceptionInspection */
501-
$yielded = $this->callbackFiber->isStarted()
502-
? $this->callbackFiber->resume()
503-
: $this->callbackFiber->start();
501+
if ($this->callbackFiber->isSuspended()) {
502+
$yielded = $this->callbackFiber->resume();
503+
} else {
504+
if ($this->callbackFiber->isTerminated()) {
505+
$this->createCallbackFiber();
506+
}
507+
$yielded = $this->callbackFiber->start();
508+
}
504509

505510
if ($yielded !== $this->internalSuspensionMarker) {
506511
$this->createCallbackFiber();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Issue #105: Ensure the callback fiber is always alive as long as the event loop lives
3+
--FILE--
4+
<?php
5+
6+
use Revolt\EventLoop;
7+
8+
require 'vendor/autoload.php';
9+
10+
final class a {
11+
private static self $a;
12+
public static function getInstance(): self {
13+
return self::$a ??= new self;
14+
}
15+
16+
public function __destruct()
17+
{
18+
echo "Destroying ", self::class, "\n";
19+
$suspension = EventLoop::getSuspension();
20+
EventLoop::delay(1.0, $suspension->resume(...));
21+
$suspension->suspend();
22+
echo "Finished " . self::class, "\n";
23+
}
24+
}
25+
26+
EventLoop::defer(function () {
27+
echo "start\n";
28+
});
29+
30+
a::getInstance();
31+
32+
EventLoop::run();
33+
34+
?>
35+
--EXPECT--
36+
start
37+
Destroying a
38+
Finished a

0 commit comments

Comments
 (0)