From f5d64b4d68ac93c1abef8ae2fd17c101f7da6ce5 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Wed, 16 Dec 2020 21:44:06 -0300
Subject: [PATCH] Terminate application before services (#1812)

* Terminate application before services

* Use flags instead of title ID
---
 Ryujinx.HLE/HOS/Horizon.cs | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index e6e9cbb0b7..9309ae4124 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -32,6 +32,7 @@ using Ryujinx.HLE.Loaders.Executables;
 using Ryujinx.HLE.Utilities;
 using System;
 using System.IO;
+using System.Linq;
 using System.Threading;
 
 namespace Ryujinx.HLE.HOS
@@ -318,8 +319,6 @@ namespace Ryujinx.HLE.HOS
 
                 _isDisposed = true;
 
-                SurfaceFlinger.Dispose();
-
                 KProcess terminationProcess = new KProcess(KernelContext);
                 KThread terminationThread = new KThread(KernelContext);
 
@@ -328,7 +327,18 @@ namespace Ryujinx.HLE.HOS
                     // Force all threads to exit.
                     lock (KernelContext.Processes)
                     {
-                        foreach (KProcess process in KernelContext.Processes.Values)
+                        // Terminate application.
+                        foreach (KProcess process in KernelContext.Processes.Values.Where(x => x.Flags.HasFlag(ProcessCreationFlags.IsApplication)))
+                        {
+                            process.Terminate();
+                        }
+
+                        // The application existed, now surface flinger can exit too.
+                        SurfaceFlinger.Dispose();
+
+                        // Terminate HLE services (must be done after the application is already terminated,
+                        // otherwise the application will receive errors due to service termination.
+                        foreach (KProcess process in KernelContext.Processes.Values.Where(x => !x.Flags.HasFlag(ProcessCreationFlags.IsApplication)))
                         {
                             process.Terminate();
                         }