citra-emu
/
citra
Archived
1
0
Fork 0

Kernel: Remove a thread from all of its waiting objects' waiting_threads list when it is awoken.

This fixes a potential bug where threads would not get removed from said list if they awoke after waiting with WaitSynchronizationN with wait_all = false
This commit is contained in:
Subv 2017-01-04 11:37:19 -05:00
parent fd95b6ee26
commit 7f1dca8cd2
1 changed files with 4 additions and 18 deletions

View File

@ -32,19 +32,6 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
}
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
// Remove the threads that are ready or already running from our waitlist
auto to_remove = waiting_threads.end();
do {
to_remove = std::find_if(waiting_threads.begin(), waiting_threads.end(),
[](const SharedPtr<Thread>& thread) {
return thread->status == THREADSTATUS_RUNNING ||
thread->status == THREADSTATUS_READY ||
thread->status == THREADSTATUS_DEAD;
});
// Call RemoveWaitingThread so that child classes can override the behavior.
RemoveWaitingThread(to_remove->get());
} while (to_remove != waiting_threads.end());
Thread* candidate = nullptr;
s32 candidate_priority = THREADPRIO_LOWEST + 1;
@ -86,17 +73,16 @@ void WaitObject::WakeupAllWaitingThreads() {
} else {
for (auto& object : thread->wait_objects) {
object->Acquire(thread.get());
object->RemoveWaitingThread(thread.get());
}
// Note: This case doesn't update the output index of WaitSynchronizationN.
// Clear the thread's waitlist
thread->wait_objects.clear();
}
for (auto& object : thread->wait_objects)
object->RemoveWaitingThread(thread.get());
thread->wait_objects.clear();
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
thread->ResumeFromWait();
// Note: Removing the thread from the object's waitlist will be
// done by GetHighestPriorityReadyThread.
}
}