Fix guest shutdown when VideoOut window is closed (#184)

Propagate Silk window close to runtime teardown so audio and CPU workers stop instead of continuing after the presentation window is dismissed.
This commit is contained in:
Mike Saito
2026-07-15 00:52:01 +03:00
committed by GitHub
parent d2f3511002
commit caf859cc52
7 changed files with 191 additions and 4 deletions
@@ -576,6 +576,10 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
// thread entering a freed stub).
private volatile bool _guestTeardownRequested;
private volatile bool _hostShutdownRequested;
private static volatile DirectExecutionBackend? _activeSessionBackend;
private int _readyGuestThreadCount;
private readonly Dictionary<ulong, GuestThreadState> _guestThreads = new Dictionary<ulong, GuestThreadState>();
@@ -812,7 +816,8 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
private bool ActiveForcedGuestExit
{
get => HasActiveExecutionThread ? _activeForcedGuestExit : _forcedGuestExit;
get => _hostShutdownRequested ||
(HasActiveExecutionThread ? _activeForcedGuestExit : _forcedGuestExit);
set
{
if (HasActiveExecutionThread)
@@ -974,7 +979,10 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
_importLoopGuardSeconds = GetImportLoopGuardSeconds();
_entryReturnSentinelRip = 0uL;
_forcedGuestExit = false;
_hostShutdownRequested = false;
_guestTeardownRequested = false;
_activeSessionBackend = this;
HostSessionControl.SetShutdownHandler(RequestHostShutdown);
_importLoopSignatureCount = 0;
_importLoopSignatureWriteIndex = 0;
_importLoopPatternHits = 0;
@@ -1022,12 +1030,28 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
}
finally
{
HostSessionControl.SetShutdownHandler(null);
if (ReferenceEquals(_activeSessionBackend, this))
{
_activeSessionBackend = null;
}
DrainDeferredBootstrapTraces();
GuestThreadExecution.Scheduler = previousGuestThreadScheduler;
Console.Error.WriteLine("[LOADER][INFO] === Execute END (LastError: " + (LastError ?? "null") + ") ===");
}
}
internal void RequestHostShutdown(string reason)
{
_hostShutdownRequested = true;
_forcedGuestExit = true;
_guestTeardownRequested = true;
LastError = string.IsNullOrWhiteSpace(reason)
? "Host shutdown requested."
: $"Host shutdown requested: {reason}";
Console.Error.WriteLine($"[LOADER][INFO] {LastError}");
}
private bool SetupImportStubs(IReadOnlyDictionary<ulong, string> importStubs)
{
Console.Error.WriteLine($"[LOADER][INFO] Setting up {importStubs.Count} import stubs...");
@@ -4425,7 +4449,9 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
result = OrbisGen2Result.ORBIS_GEN2_ERROR_CPU_TRAP;
if (string.IsNullOrEmpty(LastError))
{
LastError = "Detected repeating import loop and forced guest unwind to host.";
LastError = _hostShutdownRequested
? "Host shutdown requested."
: "Detected repeating import loop and forced guest unwind to host.";
}
Console.Error.WriteLine("[LOADER][ERROR] " + LastError);
RequestGuestThreadTeardown(3000);