From d54633f09f3e564e6d400b45167a2267c9d074ad Mon Sep 17 00:00:00 2001 From: Victor239 <12621257+Victor239@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:52:01 +0000 Subject: [PATCH] Fix SIGINT not closing Grayjay in headless/server mode Register Console.CancelKeyPress and AppDomain.ProcessExit handlers to cancel the shared CancellationTokenSource on SIGINT/SIGTERM. This unblocks the WaitHandle.WaitOne() call in headless mode (and the WaitForExitAsync call in windowed mode), allowing cleanup to run and the process to exit gracefully. Fixes #569 --- Grayjay.Desktop.CEF/Program.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Grayjay.Desktop.CEF/Program.cs b/Grayjay.Desktop.CEF/Program.cs index 70e86790..b70aa359 100644 --- a/Grayjay.Desktop.CEF/Program.cs +++ b/Grayjay.Desktop.CEF/Program.cs @@ -443,8 +443,21 @@ static async Task EntryPoint(string[] args) //Logger.i(nameof(Program), $"Main: EnableClient finished ({watch.ElapsedMilliseconds}ms)"); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); - GrayjayServer server = new GrayjayServer((!isServer && cef != null ? new CEFWindowProvider(cef) : null), - isHeadless, + + Console.CancelKeyPress += (sender, e) => + { + e.Cancel = true; // Prevent immediate termination; handle gracefully below + Logger.i(nameof(Program), "Received SIGINT, shutting down gracefully."); + cancellationTokenSource.Cancel(); + }; + + AppDomain.CurrentDomain.ProcessExit += (sender, e) => + { + cancellationTokenSource.Cancel(); + }; + + GrayjayServer server = new GrayjayServer((!isServer && cef != null ? new CEFWindowProvider(cef) : null), + isHeadless, isServer); _ = Task.Run(async () => {