aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/wait_object.cpp
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-01-08 11:35:03 -0500
committerbunnei <bunneidev@gmail.com>2018-01-08 21:12:49 -0500
commitac8f05943b9682a2c4b69da8c6bdd39cfbcf883f (patch)
tree0976e02e0b495f07b11a51811618199d791d4c4e /src/core/hle/kernel/wait_object.cpp
parent19ba66ac8ef278bf9828acdf3d131ab9e1c7239f (diff)
Kernel: Allow chaining WaitSynchronization calls inside a wakeup callback.
Diffstat (limited to 'src/core/hle/kernel/wait_object.cpp')
-rw-r--r--src/core/hle/kernel/wait_object.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index c942a40fa7..ec147b84ca 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -68,6 +68,8 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
}
void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
+ ASSERT(!ShouldWait(thread.get()));
+
if (!thread)
return;
@@ -75,19 +77,26 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
Acquire(thread.get());
} else {
for (auto& object : thread->wait_objects) {
+ ASSERT(!object->ShouldWait(thread.get()));
object->Acquire(thread.get());
}
}
- // Invoke the wakeup callback before clearing the wait objects
- if (thread->wakeup_callback)
- thread->wakeup_callback(ThreadWakeupReason::Signal, thread, this);
+ size_t index = thread->GetWaitObjectIndex(this);
for (auto& object : thread->wait_objects)
object->RemoveWaitingThread(thread.get());
thread->wait_objects.clear();
- thread->ResumeFromWait();
+ thread->CancelWakeupTimer();
+
+ bool resume = true;
+
+ if (thread->wakeup_callback)
+ resume = thread->wakeup_callback(ThreadWakeupReason::Signal, thread, this, index);
+
+ if (resume)
+ thread->ResumeFromWait();
}
void WaitObject::WakeupAllWaitingThreads() {