mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-24 11:48:39 +08:00
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:
@@ -238,6 +238,22 @@ public sealed partial class DirectExecutionBackend
|
||||
cpuContext[CpuRegister.Rax] = 0uL;
|
||||
return 0uL;
|
||||
}
|
||||
if (_hostShutdownRequested)
|
||||
{
|
||||
if (isGuestWorker &&
|
||||
TryYieldGuestThreadToHostStub(argPackPtr, num, num7, importStubEntry.Nid, "host shutdown"))
|
||||
{
|
||||
cpuContext[CpuRegister.Rax] = 0uL;
|
||||
return 0uL;
|
||||
}
|
||||
|
||||
if (!isGuestWorker &&
|
||||
TryAbortGuestForHostShutdown(argPackPtr, num, num7))
|
||||
{
|
||||
cpuContext[CpuRegister.Rax] = 1uL;
|
||||
return 1uL;
|
||||
}
|
||||
}
|
||||
bool flag0 = ShouldSuppressStrlenTrace(importStubEntry.Nid);
|
||||
bool flag = num7 >= 2156221920u && num7 <= 2156225024u;
|
||||
bool flag2 = num7 >= 2156351360u && num7 <= 2156352080u;
|
||||
@@ -975,6 +991,31 @@ public sealed partial class DirectExecutionBackend
|
||||
return true;
|
||||
}
|
||||
|
||||
private unsafe bool TryAbortGuestForHostShutdown(nint argPackPtr, long dispatchIndex, ulong returnRip)
|
||||
{
|
||||
ulong hostExit = ActiveEntryReturnSentinelRip;
|
||||
if (hostExit < 65536 || !TryPatchActiveGuestReturnSlot(hostExit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
*(ulong*)(argPackPtr + 96) = hostExit;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ActiveForcedGuestExit = true;
|
||||
if (string.IsNullOrWhiteSpace(LastError))
|
||||
{
|
||||
LastError = "Host shutdown requested.";
|
||||
}
|
||||
Console.Error.WriteLine(
|
||||
$"[LOADER][INFO] Guest unwind for host shutdown at import#{dispatchIndex} ret=0x{returnRip:X16} -> host_exit=0x{hostExit:X16}");
|
||||
return true;
|
||||
}
|
||||
|
||||
private unsafe bool TryCompleteGuestEntryToHostStub(nint argPackPtr, long dispatchIndex, ulong returnRip, string nid, string reason, ulong value)
|
||||
{
|
||||
ulong hostExit = ActiveEntryReturnSentinelRip;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user