Skip to content

Commit

Permalink
Register shutdown function to clear event loop
Browse files Browse the repository at this point in the history
  • Loading branch information
trowski committed Dec 7, 2024
1 parent 358572c commit bc4cfa6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
36 changes: 36 additions & 0 deletions examples/shutdown.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Revolt\EventLoop;

\register_shutdown_function(function (): void {
\register_shutdown_function(function (): void {
EventLoop::defer(function (): void {
print 'Shutdown function registered within pre-loop-run shutdown function' . PHP_EOL;
});
});


EventLoop::defer(function (): void {
print 'Shutdown function registered before EventLoop::run()' . PHP_EOL;
});
});

EventLoop::run();

\register_shutdown_function(function (): void {
\register_shutdown_function(function (): void {
EventLoop::defer(function (): void {
print 'Shutdown function registered within post-loop-run shutdown function' . PHP_EOL;
});
});

EventLoop::defer(function (): void {
print 'Shutdown function registered after EventLoop::run()' . PHP_EOL;
});
});

print 'End of script' . PHP_EOL;
29 changes: 27 additions & 2 deletions src/EventLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ final class EventLoop
public static function setDriver(Driver $driver): void
{
/** @psalm-suppress RedundantPropertyInitializationCheck, RedundantCondition */
if (isset(self::$driver) && self::$driver->isRunning()) {
throw new \Error("Can't swap the event loop driver while the driver is running");
if (isset(self::$driver)) {
if (self::$driver->isRunning()) {
throw new \Error("Can't swap the event loop driver while the driver is running");
}
} else {
\register_shutdown_function(self::onShutdown(...), 0);
}

try {
Expand Down Expand Up @@ -67,6 +71,27 @@ protected function now(): float
}
}

private static function onShutdown(int $invocationCount): void
{
$driver = self::getDriver();

$pending = false;
foreach ($driver->getIdentifiers() as $identifier) {
if ($driver->isEnabled($identifier) && $driver->isReferenced($identifier)) {
$pending = true;
break;
}
}

if ($pending) {
$driver->run();
}

if (!$invocationCount++ || $pending) {
\register_shutdown_function(self::onShutdown(...), $invocationCount);
}
}

/**
* Queue a microtask.
*
Expand Down

0 comments on commit bc4cfa6

Please sign in to comment.