mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 20:33:10 +00:00
SystemServer: Wait on all waitable children in SIGCHLD handler
We need to call waitpid until no more waitable children are available. This is necessary because SIGCHLD signals may coalesce into one when multiple children terminate almost simultaneously. This fixes random zombie processes sticking around after e.g. closing Browser. Also, switch to EventLoop's asynchronous signal handling mechanism, which allows more complex operations in the signal handler.
This commit is contained in:
parent
ddaab598a7
commit
d6174f9c79
|
@ -42,29 +42,28 @@ String g_boot_mode = "graphical";
|
|||
|
||||
static void sigchld_handler(int)
|
||||
{
|
||||
int status = 0;
|
||||
pid_t pid = waitpid(-1, &status, WNOHANG);
|
||||
if (!pid)
|
||||
return;
|
||||
for (;;) {
|
||||
int status = 0;
|
||||
pid_t pid = waitpid(-1, &status, WNOHANG);
|
||||
if (pid < 0) {
|
||||
perror("waitpid");
|
||||
break;
|
||||
}
|
||||
if (pid == 0)
|
||||
break;
|
||||
|
||||
#ifdef SYSTEMSERVER_DEBUG
|
||||
dbg() << "Reaped child with pid " << pid << ", exit status " << status;
|
||||
dbg() << "Reaped child with pid " << pid << ", exit status " << status;
|
||||
#endif
|
||||
|
||||
Service* service = Service::find_by_pid(pid);
|
||||
if (service == nullptr) {
|
||||
// This can happen for multi-instance services.
|
||||
return;
|
||||
}
|
||||
Service* service = Service::find_by_pid(pid);
|
||||
if (service == nullptr) {
|
||||
// This can happen for multi-instance services.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Call service->did_exit(status) some time soon.
|
||||
// We wouldn't want to run the complex logic, such
|
||||
// as possibly spawning the service again, from the
|
||||
// signal handler, so defer it.
|
||||
Core::EventLoop::main().post_event(*service, make<Core::DeferredInvocationEvent>([=](auto&) {
|
||||
service->did_exit(status);
|
||||
}));
|
||||
Core::EventLoop::wake();
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_boot_mode()
|
||||
|
@ -112,15 +111,10 @@ int main(int, char**)
|
|||
mount_all_filesystems();
|
||||
parse_boot_mode();
|
||||
|
||||
struct sigaction sa = {
|
||||
.sa_handler = sigchld_handler,
|
||||
.sa_mask = 0,
|
||||
.sa_flags = SA_RESTART
|
||||
};
|
||||
sigaction(SIGCHLD, &sa, nullptr);
|
||||
|
||||
Core::EventLoop event_loop;
|
||||
|
||||
event_loop.register_signal(SIGCHLD, sigchld_handler);
|
||||
|
||||
// Read our config and instantiate services.
|
||||
// This takes care of setting up sockets.
|
||||
NonnullRefPtrVector<Service> services;
|
||||
|
|
Loading…
Reference in a new issue