From 446025fb65989dff02f1ab4fd1149ebf616fc45d Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Mon, 28 Feb 2022 20:06:49 -0800 Subject: [PATCH] [kernel] Add clear() method to wait_queue Allow objects to clear out the wait_queue earlier than waiting for the destructor by moving that functionality into wait_queue::clear(). --- src/kernel/objects/channel.cpp | 1 + src/kernel/objects/mailbox.cpp | 2 +- src/kernel/wait_queue.cpp | 21 ++++++++++++--------- src/kernel/wait_queue.h | 3 +++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/kernel/objects/channel.cpp b/src/kernel/objects/channel.cpp index 71b3bc4..9111910 100644 --- a/src/kernel/objects/channel.cpp +++ b/src/kernel/objects/channel.cpp @@ -76,6 +76,7 @@ void channel::close() { util::scoped_lock lock {m_close_lock}; + m_queue.clear(); g_kernel_buffers.return_section(m_data); m_closed = true; } diff --git a/src/kernel/objects/mailbox.cpp b/src/kernel/objects/mailbox.cpp index 63f6876..8a6fe08 100644 --- a/src/kernel/objects/mailbox.cpp +++ b/src/kernel/objects/mailbox.cpp @@ -41,8 +41,8 @@ mailbox::close() for (auto &p : m_pending) { delete p.val.msg; - p.val.sender->wake(no_message); } + m_queue.clear(); } void diff --git a/src/kernel/wait_queue.cpp b/src/kernel/wait_queue.cpp index 9920830..84584e9 100644 --- a/src/kernel/wait_queue.cpp +++ b/src/kernel/wait_queue.cpp @@ -1,14 +1,7 @@ #include "objects/thread.h" #include "wait_queue.h" -wait_queue::~wait_queue() -{ - util::scoped_lock lock {m_lock}; - for (auto *t : m_threads) { - if (!t->exited()) t->wake(); - t->handle_release(); - } -} +wait_queue::~wait_queue() { clear(); } void wait_queue::add_thread(obj::thread *t) @@ -23,7 +16,7 @@ wait_queue::pop_exited() { while (!m_threads.empty()) { obj::thread *t = m_threads.first(); - if (!t->exited()) + if (!t->exited() && !t->ready()) break; m_threads.pop_front(); @@ -48,3 +41,13 @@ wait_queue::pop_next_unlocked() return nullptr; return m_threads.pop_front(); } + +void +wait_queue::clear() +{ + util::scoped_lock lock {m_lock}; + for (auto *t : m_threads) { + if (!t->exited()) t->wake(); + t->handle_release(); + } +} diff --git a/src/kernel/wait_queue.h b/src/kernel/wait_queue.h index a440f83..14fe3b1 100644 --- a/src/kernel/wait_queue.h +++ b/src/kernel/wait_queue.h @@ -37,6 +37,9 @@ public: /// Get the spinlock to lock this queue util::spinlock & get_lock() { return m_lock; } + /// Wake and clear out all threads. + void clear(); + private: /// Get rid of any exited threads that are next /// in the queue. Caller must hold the queue lock.