From f41e254e357880297486cd5cabf5a9148c1f30dc Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 10 Aug 2025 15:31:42 +0300 Subject: [PATCH] Kernel: Fix dead lock on process exit --- kernel/include/kernel/Process.h | 2 ++ kernel/kernel/Process.cpp | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 318a0b17..b71a92bf 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -334,6 +334,8 @@ namespace Kernel BAN::Vector m_child_exit_statuses; ThreadBlocker m_child_exit_blocker; + BAN::Atomic m_is_exiting { false }; + bool m_has_called_exec { false }; BAN::UniqPtr m_page_table; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index f62914d7..6e360abb 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -257,6 +257,16 @@ namespace Kernel void Process::exit(int status, int signal) { + bool expected = false; + if (!m_is_exiting.compare_exchange(expected, true)) + { + Thread::current().on_exit(); + ASSERT_NOT_REACHED(); + } + + const auto state = Processor::get_interrupt_state(); + Processor::set_interrupt_state(InterruptState::Enabled); + if (m_parent) { Process* parent_process = nullptr; @@ -294,13 +304,18 @@ namespace Kernel } } - for (size_t i = 0; i < m_threads.size(); i++) { - if (m_threads[i] == &Thread::current()) - continue; - m_threads[i]->add_signal(SIGKILL); + LockGuard _(m_process_lock); + for (auto* thread : m_threads) + if (thread != &Thread::current()) + ASSERT(thread->add_signal(SIGKILL)); } + while (m_threads.size() > 1) + Processor::yield(); + + Processor::set_interrupt_state(state); + Thread::current().on_exit(); ASSERT_NOT_REACHED(); @@ -507,7 +522,6 @@ namespace Kernel BAN::ErrorOr Process::sys_exit(int status) { ASSERT(this == &Process::current()); - LockGuard _(m_process_lock); exit(status, 0); ASSERT_NOT_REACHED(); }