Преглед на файлове

Kernel: Don't send SIGCHLD to parent process if he has SA_NOCLDWAIT set.

Just transfer ownership of the dead process to the colonel and let the
scheduler reap it on next iteration.
Andreas Kling преди 6 години
родител
ревизия
274b0260f7
променени са 3 файла, в които са добавени 18 реда и са изтрити 2 реда
  1. 11 0
      Applications/FileManager/main.cpp
  2. 6 1
      Kernel/Process.cpp
  3. 1 1
      Kernel/Scheduler.cpp

+ 11 - 0
Applications/FileManager/main.cpp

@@ -7,11 +7,22 @@
 #include <LibGUI/GMenuBar.h>
 #include <LibGUI/GAction.h>
 #include <unistd.h>
+#include <signal.h>
 #include <stdio.h>
 #include "DirectoryTableView.h"
 
 int main(int argc, char** argv)
 {
+    struct sigaction act;
+    memset(&act, 0, sizeof(act));
+    act.sa_flags = SA_NOCLDWAIT;
+    act.sa_handler = SIG_IGN;
+    int rc = sigaction(SIGCHLD, &act, nullptr);
+    if (rc < 0) {
+        perror("sigaction");
+        return 1;
+    }
+
     GApplication app(argc, argv);
 
     auto mkdir_action = GAction::create("New directory...", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/mkdir16.rgb", { 16, 16 }), [] (const GAction&) {

+ 6 - 1
Kernel/Process.cpp

@@ -2202,7 +2202,12 @@ void Process::finalize()
     {
         InterruptDisabler disabler;
         if (auto* parent_process = Process::from_pid(m_ppid)) {
-            parent_process->send_signal(SIGCHLD, this);
+            if (parent_process->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) {
+                // NOTE: If the parent doesn't care about this process, let it go.
+                m_ppid = 0;
+            } else {
+                parent_process->send_signal(SIGCHLD, this);
+            }
         }
     }
 

+ 1 - 1
Kernel/Scheduler.cpp

@@ -138,7 +138,7 @@ bool Scheduler::pick_next()
         }
 
         if (process.state() == Process::Dead) {
-            if (current != &process && !Process::from_pid(process.ppid())) {
+            if (current != &process && (!process.ppid() || !Process::from_pid(process.ppid()))) {
                 auto name = process.name();
                 auto pid = process.pid();
                 auto exit_status = Process::reap(process);