Kernel: Fix dead lock on process exit

This commit is contained in:
Bananymous 2025-08-10 15:31:42 +03:00
parent 7e472a9c1d
commit f41e254e35
2 changed files with 21 additions and 5 deletions

View File

@ -334,6 +334,8 @@ namespace Kernel
BAN::Vector<ChildExitStatus> m_child_exit_statuses; BAN::Vector<ChildExitStatus> m_child_exit_statuses;
ThreadBlocker m_child_exit_blocker; ThreadBlocker m_child_exit_blocker;
BAN::Atomic<bool> m_is_exiting { false };
bool m_has_called_exec { false }; bool m_has_called_exec { false };
BAN::UniqPtr<PageTable> m_page_table; BAN::UniqPtr<PageTable> m_page_table;

View File

@ -257,6 +257,16 @@ namespace Kernel
void Process::exit(int status, int signal) 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) if (m_parent)
{ {
Process* parent_process = nullptr; 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()) LockGuard _(m_process_lock);
continue; for (auto* thread : m_threads)
m_threads[i]->add_signal(SIGKILL); 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(); Thread::current().on_exit();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -507,7 +522,6 @@ namespace Kernel
BAN::ErrorOr<long> Process::sys_exit(int status) BAN::ErrorOr<long> Process::sys_exit(int status)
{ {
ASSERT(this == &Process::current()); ASSERT(this == &Process::current());
LockGuard _(m_process_lock);
exit(status, 0); exit(status, 0);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }