diff options
| author | Thog <me@thog.eu> | 2019-12-26 02:50:17 +0100 |
|---|---|---|
| committer | Ac_K <Acoustik666@gmail.com> | 2019-12-26 02:50:17 +0100 |
| commit | 55c956e2ec83b2b7f414688c4fe4ed9f1f316935 (patch) | |
| tree | a543fffefd7b014d6f4a7c5688040e68edcbe018 /Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs | |
| parent | 87bfe681ef65ed692aa1e46e3f5f8229013cf46a (diff) | |
Make HLE disposable safely (#850)
* Make HLE disposable safely
This fix the oldest issue with the HLE code: the kernel side
disposability.
Changelog:
- Implement KProcess::UnpauseAndTerminateAllThreadsExcept, KThread::Terminate, KThread::TerminateCurrentProcess, KThread::PrepareForTermiation and the svc post handler accurately.
- Implement svcTerminateProcess and svcExitProcess. (both untested)
- Fix KHandleTable::Destroy not decrementing refcount of all objects stored in the table.
- Spawn a custom KProcess with the maximum priority to terminate every guest KProcess. (terminating kernel emulation safely)
- General system stability improvements to enhance the user's experience.
* Fix a typo in a comment in KProcess.cs
* Address gdk's comments
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs index 6525628f..7961f124 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs @@ -17,9 +17,41 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall ExitProcess(); } + public KernelResult TerminateProcess64(int handle) + { + return TerminateProcess(handle); + } + + private KernelResult TerminateProcess(int handle) + { + KProcess process = _process.HandleTable.GetObject<KProcess>(handle); + + KernelResult result; + + if (process != null) + { + if (process == _system.Scheduler.GetCurrentProcess()) + { + result = KernelResult.Success; + process.DecrementToZeroWhileTerminatingCurrent(); + } + else + { + result = process.Terminate(); + process.DecrementReferenceCount(); + } + } + else + { + result = KernelResult.InvalidHandle; + } + + return result; + } + private void ExitProcess() { - _system.Scheduler.GetCurrentProcess().Terminate(); + _system.Scheduler.GetCurrentProcess().TerminateCurrentProcess(); } public KernelResult SignalEvent64(int handle) @@ -184,6 +216,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { currentThread.PrintGuestStackTrace(); + // As the process is exiting, this is probably caused by emulation termination. + if (currentThread.Owner.State == ProcessState.Exiting) + { + return; + } + + // TODO: Debug events. + currentThread.Owner.TerminateCurrentProcess(); + throw new GuestBrokeExecutionException(); } else |
