From 1df2c5ce7f52f34bb01e392e8bc4b00cc691614a Mon Sep 17 00:00:00 2001 From: Cristian Carlesso Date: Thu, 15 Feb 2018 12:16:16 +0000 Subject: [PATCH] Gracefully close the app on exit (#12) * Gracefully close the app on exit * Application tear down instead of calling Environment.Exit(0); do a better tear down of the application --- Program.cs | 4 ++++ Ryujinx/OsHle/Horizon.cs | 13 +++++++++++++ Ryujinx/OsHle/Process.cs | 4 ++-- Ryujinx/OsHle/Svc/SvcHandler.cs | 2 +- Ryujinx/OsHle/Svc/SvcSystem.cs | 2 ++ Ryujinx/Switch.cs | 9 +++++++++ 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Program.cs b/Program.cs index 3d4481aa51..88a8a117c3 100644 --- a/Program.cs +++ b/Program.cs @@ -50,6 +50,10 @@ namespace Ryujinx using (GLScreen Screen = new GLScreen(Ns, Renderer)) { + Ns.Finish += (Sender, Args) => { + Screen.Exit(); + }; + Screen.Run(60.0); } diff --git a/Ryujinx/OsHle/Horizon.cs b/Ryujinx/OsHle/Horizon.cs index dd57873024..f31088738a 100644 --- a/Ryujinx/OsHle/Horizon.cs +++ b/Ryujinx/OsHle/Horizon.cs @@ -4,6 +4,7 @@ using Ryujinx.OsHle.Handles; using Ryujinx.OsHle.Utilities; using System.Collections.Concurrent; using System.IO; +using System; namespace Ryujinx.OsHle { @@ -136,6 +137,18 @@ namespace Ryujinx.OsHle } } + internal bool ExitProcess(int ProcessId) { + Process process; + var Success = Processes.TryRemove(ProcessId, out process); + if (Success) { + process.StopAllThreads(); + } + + if (Processes.Count == 0) { + Ns.OnFinish(EventArgs.Empty); + } + return Success; + } internal bool TryGetProcess(int ProcessId, out Process Process) { if (!Processes.TryGetValue(ProcessId, out Process)) diff --git a/Ryujinx/OsHle/Process.cs b/Ryujinx/OsHle/Process.cs index 653d9dfda7..05f12c1a4b 100644 --- a/Ryujinx/OsHle/Process.cs +++ b/Ryujinx/OsHle/Process.cs @@ -116,7 +116,7 @@ namespace Ryujinx.OsHle { if (MainThread != null) { - while (MainThread.Thread.IsAlive) + if (MainThread.Thread.IsAlive) { MainThread.Thread.StopExecution(); } @@ -124,7 +124,7 @@ namespace Ryujinx.OsHle foreach (AThread Thread in TlsSlots.Values) { - while (Thread.IsAlive) + if (Thread.IsAlive) { Thread.StopExecution(); } diff --git a/Ryujinx/OsHle/Svc/SvcHandler.cs b/Ryujinx/OsHle/Svc/SvcHandler.cs index ad228c45d8..2191793a09 100644 --- a/Ryujinx/OsHle/Svc/SvcHandler.cs +++ b/Ryujinx/OsHle/Svc/SvcHandler.cs @@ -8,7 +8,6 @@ namespace Ryujinx.OsHle.Svc partial class SvcHandler { private delegate void SvcFunc(ARegisters Registers); - private Dictionary SvcFuncs; private Switch Ns; @@ -25,6 +24,7 @@ namespace Ryujinx.OsHle.Svc { 0x03, SvcSetMemoryAttribute }, { 0x04, SvcMapMemory }, { 0x06, SvcQueryMemory }, + { 0x07, SvcExitProcess }, { 0x08, SvcCreateThread }, { 0x09, SvcStartThread }, { 0x0b, SvcSleepThread }, diff --git a/Ryujinx/OsHle/Svc/SvcSystem.cs b/Ryujinx/OsHle/Svc/SvcSystem.cs index 098ddb2f67..09f7e74c39 100644 --- a/Ryujinx/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx/OsHle/Svc/SvcSystem.cs @@ -9,6 +9,8 @@ namespace Ryujinx.OsHle.Svc { partial class SvcHandler { + private void SvcExitProcess(ARegisters Registers) => Ns.Os.ExitProcess(Registers.ProcessId); + private void SvcCloseHandle(ARegisters Registers) { int Handle = (int)Registers.X0; diff --git a/Ryujinx/Switch.cs b/Ryujinx/Switch.cs index 9e5ea7d06c..e912da86b3 100644 --- a/Ryujinx/Switch.cs +++ b/Ryujinx/Switch.cs @@ -24,6 +24,15 @@ namespace Ryujinx VFs = new VirtualFs(); } + public event EventHandler Finish; + internal virtual void OnFinish(EventArgs e) + { + EventHandler Handler = Finish; + if (Handler != null) + { + Handler(this, e); + } + } public void Dispose() { Dispose(true);