From 85527cc7c7dfce81278d0373ffce97c70e35d5d7 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Wed, 2 Nov 2022 20:08:19 -0400
Subject: kernel: avoid racy behavior in global suspension

---
 src/core/hle/kernel/kernel.cpp | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

(limited to 'src/core/hle/kernel/kernel.cpp')

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 09c36ee09d..6df77b4239 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -1109,16 +1109,28 @@ void KernelCore::Suspend(bool suspended) {
     const bool should_suspend{exception_exited || suspended};
     const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
 
-    for (auto* process : GetProcessList()) {
-        process->SetActivity(activity);
+    std::vector<KScopedAutoObject<KThread>> process_threads;
+    {
+        KScopedSchedulerLock sl{*this};
+
+        if (auto* process = CurrentProcess(); process != nullptr) {
+            process->SetActivity(activity);
+
+            if (!should_suspend) {
+                // Runnable now; no need to wait.
+                return;
+            }
 
-        if (should_suspend) {
-            // Wait for execution to stop
             for (auto* thread : process->GetThreadList()) {
-                thread->WaitUntilSuspended();
+                process_threads.emplace_back(thread);
             }
         }
     }
+
+    // Wait for execution to stop.
+    for (auto& thread : process_threads) {
+        thread->WaitUntilSuspended();
+    }
 }
 
 void KernelCore::ShutdownCores() {
-- 
cgit v1.2.3-70-g09d2