// Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later namespace SharpEmu.HLE; /// /// Lets host-facing libraries (VideoOut, AudioOut) request cooperative guest /// shutdown without taking a dependency on SharpEmu.Core. /// public static class HostSessionControl { private static Action? _shutdownHandler; private static string? _pendingShutdownReason; private static int _shutdownRequested; /// /// Indicates that the active host session is being stopped. Runtime code /// uses this to skip expensive post-exit diagnostics before returning the /// GUI to its library. /// public static bool IsShutdownRequested => Volatile.Read(ref _shutdownRequested) != 0; /// /// Starts a fresh session after the previous guest has fully left its /// execution backend. /// public static void ResetShutdownRequest() { Interlocked.Exchange(ref _pendingShutdownReason, null); Volatile.Write(ref _shutdownRequested, 0); } public static void SetShutdownHandler(Action? handler) { Volatile.Write(ref _shutdownHandler, handler); if (handler is null) { Interlocked.Exchange(ref _pendingShutdownReason, null); return; } var pendingReason = Interlocked.Exchange(ref _pendingShutdownReason, null); if (pendingReason is not null) { Invoke(handler, pendingReason); } } public static void RequestShutdown(string reason) { Volatile.Write(ref _shutdownRequested, 1); var handler = Volatile.Read(ref _shutdownHandler); if (handler is not null) { Invoke(handler, reason); return; } // Stop can be pressed while the GUI session is starting. Retain the // request until the native backend installs its cooperative handler. Volatile.Write(ref _pendingShutdownReason, reason); handler = Volatile.Read(ref _shutdownHandler); if (handler is not null) { var pendingReason = Interlocked.Exchange(ref _pendingShutdownReason, null); if (pendingReason is not null) { Invoke(handler, pendingReason); } } } private static void Invoke(Action handler, string reason) { try { handler(reason); } catch (Exception exception) { Console.Error.WriteLine( $"[LOADER][WARN] Host shutdown handler failed: {exception.Message}"); } } }