From 9cd87a6352d98194c2a36ec889cf6ff541a6610e Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sat, 2 Jun 2018 14:06:35 -0500
Subject: [PATCH] Kernel/Threads: A thread waking up by timeout from a
 WaitProcessWideKey may already have an assigned lock owner.

This situation may happen like so:
Thread 1 with low priority calls WaitProcessWideKey with timeout.
Thread 2 with high priority calls WaitProcessWideKey without timeout.
Thread 3 calls SignalProcessWideKey
- Thread 2 acquires the lock and awakens.
- Thread 1 can't acquire the lock and is put to sleep with the lock owner being Thread 2.
Thread 1's timeout expires, with the lock owner still being set to Thread 2.
---
 src/core/hle/kernel/thread.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 0075e4a0f..cffa7ca83 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -133,8 +133,11 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
 
         auto lock_owner = thread->lock_owner;
         // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance
-        // and don't have a lock owner.
-        ASSERT(lock_owner == nullptr);
+        // and don't have a lock owner unless SignalProcessWideKey was called first and the thread
+        // wasn't awakened due to the mutex already being acquired.
+        if (lock_owner) {
+            lock_owner->RemoveMutexWaiter(thread);
+        }
     }
 
     if (resume)