kernel: Prevent kernel threads from calling exit_and_signal_parent()
All checks were successful
Build and test / build (push) Successful in 1m53s
All checks were successful
Build and test / build (push) Successful in 1m53s
Kernel threads are supposed to use kernel_exit() instead, so it makes no sense to have an extra branch for them.
This commit is contained in:
parent
907049c405
commit
2ce2d57eff
@ -104,56 +104,53 @@ Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& pa
|
|||||||
|
|
||||||
[[noreturn]] void Thread::exit_and_signal_parent(int _status)
|
[[noreturn]] void Thread::exit_and_signal_parent(int _status)
|
||||||
{
|
{
|
||||||
|
check(!is_kernel);
|
||||||
|
|
||||||
#ifndef MOON_ENABLE_TESTING_FEATURES
|
#ifndef MOON_ENABLE_TESTING_FEATURES
|
||||||
if (this->id == 1) fail("the init process exited");
|
if (this->id == 1) fail("the init process exited");
|
||||||
#else
|
#else
|
||||||
if (this->id == 1) CPU::magic_exit(_status);
|
if (this->id == 1) CPU::magic_exit(_status);
|
||||||
#endif
|
#endif
|
||||||
if (is_kernel) {
|
|
||||||
state = ThreadState::Dying;
|
Scheduler::for_each_child(this, [](Thread* child) {
|
||||||
Scheduler::signal_reap_thread();
|
child->parent = Scheduler::init_thread();
|
||||||
}
|
return true;
|
||||||
else
|
});
|
||||||
|
|
||||||
|
if (is_session_leader())
|
||||||
{
|
{
|
||||||
Scheduler::for_each_child(this, [](Thread* child) {
|
kinfoln("thread %d is exiting as a session leader, sending signals to session", id);
|
||||||
child->parent = Scheduler::init_thread();
|
// 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;
|
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;
|
status = _status;
|
||||||
kernel_yield();
|
kernel_yield();
|
||||||
unreachable();
|
unreachable();
|
||||||
|
Loading…
Reference in New Issue
Block a user