Kernel: Fix a deadlock when process is exiting

This commit is contained in:
Bananymous 2025-06-06 06:52:02 +03:00
parent 81ff71a97f
commit a76c6faffc
1 changed files with 25 additions and 20 deletions

View File

@ -273,15 +273,23 @@ namespace Kernel
{ {
if (m_parent) if (m_parent)
{ {
Process* parent_process = nullptr;
for_each_process( for_each_process(
[&](Process& parent) -> BAN::Iteration [&](Process& parent) -> BAN::Iteration
{ {
if (parent.pid() != m_parent) if (parent.pid() != m_parent)
return BAN::Iteration::Continue; return BAN::Iteration::Continue;
parent_process = &parent;
return BAN::Iteration::Break;
}
);
LockGuard _(parent.m_process_lock); if (parent_process)
{
LockGuard _(parent_process->m_process_lock);
for (auto& child : parent.m_child_exit_statuses) for (auto& child : parent_process->m_child_exit_statuses)
{ {
if (child.pid != pid()) if (child.pid != pid())
continue; continue;
@ -289,18 +297,15 @@ namespace Kernel
child.exit_code = __WGENEXITCODE(status, signal); child.exit_code = __WGENEXITCODE(status, signal);
child.exited = true; child.exited = true;
parent.add_pending_signal(SIGCHLD); parent_process->add_pending_signal(SIGCHLD);
if (!parent.m_threads.empty()) if (!parent_process->m_threads.empty())
Processor::scheduler().unblock_thread(parent.m_threads.front()); Processor::scheduler().unblock_thread(parent_process->m_threads.front());
parent.m_child_exit_blocker.unblock(); parent_process->m_child_exit_blocker.unblock();
break; break;
} }
return BAN::Iteration::Break;
} }
);
} }
for (size_t i = 0; i < m_threads.size(); i++) for (size_t i = 0; i < m_threads.size(); i++)