diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index e35cca9e..77b7f42a 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -104,56 +104,53 @@ Result> Thread::resolve_atfile(int dirfd, const String& pa [[noreturn]] void Thread::exit_and_signal_parent(int _status) { + check(!is_kernel); + #ifndef MOON_ENABLE_TESTING_FEATURES if (this->id == 1) fail("the init process exited"); #else if (this->id == 1) CPU::magic_exit(_status); #endif - if (is_kernel) { - state = ThreadState::Dying; - Scheduler::signal_reap_thread(); - } - else + + Scheduler::for_each_child(this, [](Thread* child) { + child->parent = Scheduler::init_thread(); + return true; + }); + + if (is_session_leader()) { - Scheduler::for_each_child(this, [](Thread* child) { - child->parent = Scheduler::init_thread(); + kinfoln("thread %d is exiting as a session leader, sending signals to session", id); + // FIXME: Send SIGHUP only to the foreground process group if the session has a controlling terminal. + Scheduler::for_each_in_session(sid, [this](Thread* thread) { + if (thread == this) return true; + thread->sid = 0; + thread->controlling_terminal = {}; + thread->send_signal(SIGHUP); + kinfoln("reparenting and sending SIGHUP to %d", thread->id); return true; }); - - if (is_session_leader()) - { - kinfoln("thread %d is exiting as a session leader, sending signals to session", id); - // FIXME: Send SIGHUP only to the foreground process group if the session has a controlling terminal. - Scheduler::for_each_in_session(sid, [this](Thread* thread) { - if (thread == this) return true; - thread->sid = 0; - thread->controlling_terminal = {}; - thread->send_signal(SIGHUP); - kinfoln("reparenting and sending SIGHUP to %d", thread->id); - return true; - }); - } - - if (parent) - { - if (parent->state == ThreadState::Waiting) - { - auto child = *parent->child_being_waited_for; - if (child == -1 || child == id) - { - parent->child_being_waited_for = id; - parent->wake_up(); - } - } - else - { - while (parent->pending_signals.get(SIGCHLD - 1)) kernel_yield(); - parent->send_signal(SIGCHLD); - } - } - - state = ThreadState::Exited; } + + if (parent) + { + if (parent->state == ThreadState::Waiting) + { + auto child = *parent->child_being_waited_for; + if (child == -1 || child == id) + { + parent->child_being_waited_for = id; + parent->wake_up(); + } + } + else + { + while (parent->pending_signals.get(SIGCHLD - 1)) kernel_yield(); + parent->send_signal(SIGCHLD); + } + } + + state = ThreadState::Exited; + status = _status; kernel_yield(); unreachable();