summaryrefslogtreecommitdiff
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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)