mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-05 17:25:07 +01:00
Fix WaitForAddress
timeout mutex deadlock
Calling `WaitSchedule` inside the block where `syncWaiterMutex` is locked causes a race with other threads which lock the core mutex and `syncWaiterMutex` together. This commit moves the `WaitSchedule` outside the block while simply setting a flag to wait later similar to `ConditionVariableWait`'s timeout case. Co-authored-by: Billy Laws <blaws05@gmail.com>
This commit is contained in:
parent
4df3c98225
commit
626008d8e2
@ -425,6 +425,7 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
if (timeout > 0 && !state.scheduler->TimedWaitSchedule(std::chrono::nanoseconds(timeout))) {
|
||||
bool shouldWait{false};
|
||||
{
|
||||
std::scoped_lock lock{syncWaiterMutex};
|
||||
auto queue{syncWaiters.equal_range(address)};
|
||||
@ -434,11 +435,16 @@ namespace skyline::kernel::type {
|
||||
// We need to update the boolean flag denoting that there are no more threads waiting on this address
|
||||
__atomic_store_n(address, false, __ATOMIC_SEQ_CST);
|
||||
} else {
|
||||
state.scheduler->WaitSchedule(false);
|
||||
return {};
|
||||
// If we didn't find the thread in the queue then it must have been signalled already and we should just wait
|
||||
shouldWait = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldWait) {
|
||||
state.scheduler->WaitSchedule(false);
|
||||
return {};
|
||||
}
|
||||
|
||||
state.scheduler->InsertThread(state.thread);
|
||||
state.scheduler->WaitSchedule(false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user