summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-06-02 14:06:35 -0500
committerSubv <subv2112@gmail.com>2018-06-02 14:06:35 -0500
commit9cd87a6352d98194c2a36ec889cf6ff541a6610e (patch)
tree7589782b58ec8d4984972f6ce6a8d766d4318b97
parentbbbe34429ecaf5ccfca3b83cdd776ff78100f9d9 (diff)
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.
-rw-r--r--src/core/hle/kernel/thread.cpp7
1 files 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)