1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 14:15:01 +00:00

Kernel: Enhance WaitQueue to remember pending wakes

If WaitQueue::wake_all, WaitQueue::wake_one, or WaitQueue::wake_n
is called but nobody is currently waiting, we should remember that
fact and prevent someone from waiting after such a request. This
solves a race condition where the Finalizer thread is notified
to finalize a thread, but it is not (yet) waiting on this queue.

Fixes #2693
This commit is contained in:
Tom 2020-07-05 15:46:51 -06:00 committed by Andreas Kling
parent 2a82a25fec
commit 9725bda63e
5 changed files with 93 additions and 27 deletions

View file

@ -872,12 +872,18 @@ Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeva
// we need to wait until the scheduler lock is released again
{
ScopedSpinLock sched_lock(g_scheduler_lock);
if (!queue.enqueue(*Thread::current())) {
// The WaitQueue was already requested to wake someone when
// nobody was waiting. So return right away as we shouldn't
// be waiting
return BlockResult::NotBlocked;
}
did_unlock = unlock_process_if_locked();
if (lock)
*lock = false;
set_state(State::Queued);
m_wait_reason = reason;
queue.enqueue(*Thread::current());
if (timeout) {