diff options
author | Tom <tomut@yahoo.com> | 2020-12-07 21:29:41 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-12 21:28:12 +0100 |
commit | da5cc34ebbdfcc5b37815d369fe0c0931df54c90 (patch) | |
tree | 21b1bf721a5dce58a0ea652cee8d05d74884f002 /Kernel/Lock.cpp | |
parent | 0918d8b1f8bae11a2ef97c79564a7e7c9a394eb5 (diff) | |
download | serenity-da5cc34ebbdfcc5b37815d369fe0c0931df54c90.zip |
Kernel: Fix some issues related to fixes and block conditions
Fix some problems with join blocks where the joining thread block
condition was added twice, which lead to a crash when trying to
unblock that condition a second time.
Deferred block condition evaluation by File objects were also not
properly keeping the File object alive, which lead to some random
crashes and corruption problems.
Other problems were caused by the fact that the Queued state didn't
handle signals/interruptions consistently. To solve these issues we
remove this state entirely, along with Thread::wait_on and change
the WaitQueue into a BlockCondition instead.
Also, deliver signals even if there isn't going to be a context switch
to another thread.
Fixes #4336 and #4330
Diffstat (limited to 'Kernel/Lock.cpp')
-rw-r--r-- | Kernel/Lock.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/Kernel/Lock.cpp b/Kernel/Lock.cpp index e7c523d571..7ef642cce6 100644 --- a/Kernel/Lock.cpp +++ b/Kernel/Lock.cpp @@ -78,7 +78,8 @@ void Lock::lock(Mode mode) m_lock.store(false, AK::memory_order_release); return; } - } while (current_thread->wait_on(m_queue, m_name, nullptr, &m_lock, m_holder) == Thread::BlockResult::NotBlocked); + m_lock.store(false, AK::memory_order_release); + } while (m_queue.wait_on(nullptr, m_name) == Thread::BlockResult::NotBlocked); } else { // I don't know *who* is using "m_lock", so just yield. Scheduler::yield_from_critical(); @@ -114,7 +115,8 @@ void Lock::unlock() return; } m_mode = Mode::Unlocked; - m_queue.wake_one(&m_lock); + m_lock.store(false, AK::memory_order_release); + m_queue.wake_one(); return; } // I don't know *who* is using "m_lock", so just yield. @@ -142,7 +144,8 @@ bool Lock::force_unlock_if_locked() m_holder = nullptr; m_mode = Mode::Unlocked; m_times_locked = 0; - m_queue.wake_one(&m_lock); + m_lock.store(false, AK::memory_order_release); + m_queue.wake_one(); break; } // I don't know *who* is using "m_lock", so just yield. @@ -154,8 +157,7 @@ bool Lock::force_unlock_if_locked() void Lock::clear_waiters() { ASSERT(m_mode != Mode::Shared); - ScopedCritical critical; - m_queue.clear(); + m_queue.wake_all(); } } |