From c4b453222206f81c08adc9dc88ccf9820606b8ae Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Wed, 30 Nov 2022 03:13:39 +0530 Subject: [PATCH] Check `waitThread` rather than `waitMutex` during condvar timeouts When a timeout occurs in `ConditionVariableWait`, we used to check `waitMutex` which is cleared by `MutexUnlock` but when we hit the CAS case in `ConditionVariableSignal` then we don't clear `waitMutex`. It's far more reliable to check `waitThread` as an indication for if the thread has already been unlocked as it's cleared at the start of `ConditionVariableWait` and would implicitly stay cleared in the CAS case while being set in `MutexLock` and being unset in `MutexUnlock`. --- app/src/main/cpp/skyline/kernel/types/KProcess.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp index 70dd200b..19b2ee10 100644 --- a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp +++ b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp @@ -221,6 +221,7 @@ namespace skyline::kernel::type { { // Update all waiter information std::unique_lock lock{state.thread->waiterMutex}; + state.thread->waitThread = std::shared_ptr{nullptr}; state.thread->waitMutex = mutex; state.thread->waitTag = tag; state.thread->waitConditionVariable = key; @@ -259,7 +260,7 @@ namespace skyline::kernel::type { std::unique_lock lock{state.thread->waiterMutex}; if (state.thread->waitSignalled) { - if (state.thread->waitMutex) { + if (state.thread->waitThread) { auto waitThread{state.thread->waitThread}; std::unique_lock waitLock{waitThread->waiterMutex, std::try_to_lock}; if (!waitLock) { @@ -284,7 +285,7 @@ namespace skyline::kernel::type { shouldWait = true; } } else { - // If the waitMutex is null then we were signalled and are no longer waiting on the associated mutex + // If the waitThread is null then we were signalled and are no longer waiting on the associated mutex shouldWait = true; } } else {