From 2a3f8e8484fca54767c9874cc21f5985d2be1463 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 8 Jan 2018 11:35:03 -0500 Subject: Kernel: Allow chaining WaitSynchronization calls inside a wakeup callback. --- src/core/hle/kernel/wait_object.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index c942a40fa..ec147b84c 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -68,6 +68,8 @@ SharedPtr WaitObject::GetHighestPriorityReadyThread() { } void WaitObject::WakeupWaitingThread(SharedPtr thread) { + ASSERT(!ShouldWait(thread.get())); + if (!thread) return; @@ -75,19 +77,26 @@ void WaitObject::WakeupWaitingThread(SharedPtr 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() { -- cgit v1.2.3