diff options
| author | Liam <byteslice@airmail.cc> | 2022-11-02 20:08:19 -0400 | 
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2022-11-04 09:18:57 -0400 | 
| commit | 85527cc7c7dfce81278d0373ffce97c70e35d5d7 (patch) | |
| tree | cd59774e1d142ed346d8c97bfa0eea7fcb81c7cf | |
| parent | 9fc1bcc7b2da398d12327e8111c21e453a4af27d (diff) | |
kernel: avoid racy behavior in global suspension
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 22 | 
1 files changed, 17 insertions, 5 deletions
| diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 09c36ee09..6df77b423 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() { | 
