From 1c6a11ab142d18c3444629940f183b7c1865a5e2 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Thu, 10 Oct 2019 08:04:14 -0400
Subject: [PATCH] Kernel: Corrections to Wait Objects clearing in which a
 thread could still be signalled after a timeout or a cancel.

---
 src/core/hle/kernel/thread.cpp      | 1 +
 src/core/hle/kernel/thread.h        | 3 +++
 src/core/hle/kernel/wait_object.cpp | 3 ---
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index ae62609e38..563a99bfc7 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -133,6 +133,7 @@ void Thread::ResumeFromWait() {
 
 void Thread::CancelWait() {
     ASSERT(GetStatus() == ThreadStatus::WaitSynch);
+    ClearWaitObjects();
     SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED);
     ResumeFromWait();
 }
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 4d220c4f98..ceb4d51591 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -319,6 +319,9 @@ public:
     }
 
     void ClearWaitObjects() {
+        for (const auto& waiting_object : wait_objects) {
+            waiting_object->RemoveWaitingThread(this);
+        }
         wait_objects.clear();
     }
 
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 50ed2a2f15..0f833fb3ac 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -85,9 +85,6 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
 
     const std::size_t index = thread->GetWaitObjectIndex(this);
 
-    for (const auto& object : thread->GetWaitObjects()) {
-        object->RemoveWaitingThread(thread.get());
-    }
     thread->ClearWaitObjects();
 
     thread->CancelWakeupTimer();