diff options
author | Andreas Kling <awesomekling@gmail.com> | 2020-01-12 18:46:41 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2020-01-12 19:04:16 +0100 |
commit | 41376d46620710d4fc148b3eb3a2f4a12189c795 (patch) | |
tree | 74b562d4825f06dd1c09df227cfe726aea7a2300 /Kernel/Thread.cpp | |
parent | 61e6b1fb7c2770a2b5b56cbff5217adf8c2c4ee8 (diff) | |
download | serenity-41376d46620710d4fc148b3eb3a2f4a12189c795.zip |
Kernel: Fix Lock racing to the WaitQueue
There was a time window between releasing Lock::m_lock and calling into
the lock's WaitQueue where someone else could take m_lock and bring two
threads into a deadlock situation.
Fix this issue by holding Lock::m_lock until interrupts are disabled by
either Thread::wait_on() or WaitQueue::wake_one().
Diffstat (limited to 'Kernel/Thread.cpp')
-rw-r--r-- | Kernel/Thread.cpp | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 31e15d17b9..7e63c88ef9 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -783,10 +783,12 @@ const LogStream& operator<<(const LogStream& stream, const Thread& value) return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; } -void Thread::wait_on(WaitQueue& queue, Thread* beneficiary, const char* reason) +void Thread::wait_on(WaitQueue& queue, Atomic<bool>* lock, Thread* beneficiary, const char* reason) { bool did_unlock = unlock_process_if_locked(); cli(); + if (lock) + *lock = false; set_state(State::Queued); queue.enqueue(*current); // Yield and wait for the queue to wake us up again. |