From dc32a92aa5e992e7022595a53fb8d11f6d7341b1 Mon Sep 17 00:00:00 2001 From: fr3on Date: Sun, 5 Apr 2026 18:37:26 +0200 Subject: [PATCH] fix(runtime): add fork-safety signal guards and exception handling in Server --- src/Runtime/Server.php | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Runtime/Server.php b/src/Runtime/Server.php index edb2a03..71c1938 100644 --- a/src/Runtime/Server.php +++ b/src/Runtime/Server.php @@ -61,7 +61,12 @@ public function start(int $port = 8080): void $this->spawnWorkers($nWorkers); } else { $this->setupSignals([]); - $this->bootWorker(); + try { + $this->bootWorker(); + } catch (\Throwable $e) { + fwrite(STDERR, "[Worker " . getmypid() . "] Boot failed: {$e->getMessage()}\n"); + exit(1); + } $this->runEventLoop(); } } @@ -87,9 +92,17 @@ private function spawnWorkers(int $nWorkers): void if ($pid === 0) { // ── Child process ───────────────────────────────────────────── - // Reset signal handlers inherited from parent, then boot. - $this->setupSignals([]); - $this->bootWorker(); + // Block signals until Rust heap is owned by this process + pcntl_sigprocmask(SIG_BLOCK, [SIGTERM, SIGINT]); + try { + $this->setupSignals([]); + $this->bootWorker(); + } catch (\Throwable $e) { + fwrite(STDERR, "[Worker " . getmypid() . "] Boot failed: {$e->getMessage()}\n"); + exit(1); + } + pcntl_sigprocmask(SIG_UNBLOCK, [SIGTERM, SIGINT]); + $this->runEventLoop(); exit(0); } @@ -99,7 +112,16 @@ private function spawnWorkers(int $nWorkers): void // ── Parent process ──────────────────────────────────────────────────── $this->setupSignals($pids); - $this->bootWorker(); + try { + $this->bootWorker(); + } catch (\Throwable $e) { + fwrite(STDERR, "[Worker " . getmypid() . "] Boot failed: {$e->getMessage()}\n"); + // Kill children before exiting + foreach ($pids as $pid) { + posix_kill($pid, SIGTERM); + } + exit(1); + } $this->runEventLoop(); // Reap any remaining children after the parent's loop exits.