]> Zhao Yanbai Git Server - minix.git/commitdiff
. processes stay ZOMBIE, even after wait(), to avoid wrongly seeing them
authorBen Gras <ben@minix3.org>
Wed, 25 Oct 2006 11:29:43 +0000 (11:29 +0000)
committerBen Gras <ben@minix3.org>
Wed, 25 Oct 2006 11:29:43 +0000 (11:29 +0000)
  as living processes  before they are cleaned up (fixes
  wait()/waitpid() hanging forever on previously-ZOMBIE processes)

. stop processes from running using sys_nice() with PRIO_STOP
  when a handled signal is delivered, before computing
  stack locations for sys_sigsend(). (fixes race condition
  when runnable processes get signals, and e.g. get scheduled
  before FS sends a reply to unpause(), which can make the
  signal stack location wrong.)

servers/pm/forkexit.c
servers/pm/main.c
servers/pm/mproc.h
servers/pm/signal.c

index d12898a0fb4455cd4eab32ea4e9ce02b61ef0090..4128656c1c724abf7df0c2392cadcd022c176883 100644 (file)
@@ -326,6 +326,7 @@ int for_trace;
                rmp->mp_parent = INIT_PROC_NR;
                parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
                if (parent_waiting && (rmp->mp_flags & ZOMBIE) &&
+                       !(rmp->mp_flags & TOLD_PARENT) &&
                        rmp->mp_fs_call != PM_EXIT) {
                        cleanup(rmp);
                }
@@ -369,6 +370,7 @@ PUBLIC int do_waitpid()
                /* The value of pidarg determines which children qualify. */
                if (pidarg  > 0 && pidarg != rp->mp_pid) continue;
                if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue;
+               if (rp->mp_flags & TOLD_PARENT) continue; /* post-ZOMBIE  */
 
                children++;             /* this child is acceptable */
                if (rp->mp_flags & ZOMBIE) {
@@ -430,6 +432,8 @@ register struct mproc *child;       /* tells which process is exiting */
   mp_parent= child->mp_parent;
   if (mp_parent <= 0)
        panic(__FILE__, "tell_parent: bad value in mp_parent", mp_parent);
+  if(child->mp_flags & TOLD_PARENT)
+       panic(__FILE__, "tell_parent: telling parent again", NO_NUM);
   parent = &mproc[mp_parent];
 
   /* Wake up the parent by sending the reply message. */
@@ -437,7 +441,7 @@ register struct mproc *child;       /* tells which process is exiting */
   parent->mp_reply.reply_res2 = exitstatus;
   setreply(child->mp_parent, child->mp_pid);
   parent->mp_flags &= ~WAITING;                /* parent no longer waiting */
-  child->mp_flags &= ~ZOMBIE;          /* avoid informing parent twice */
+  child->mp_flags |= TOLD_PARENT;      /* avoid informing parent twice */
 }
 
 /*===========================================================================*
index 3f23a856610a9cd5e92dda7a712d26abab392c28..58d66f34d5f1bfa4e7fbb9c6414a8f725e5c74f9 100644 (file)
@@ -794,7 +794,7 @@ message *m_ptr;
                /* Clean up if the parent has collected the exit
                 * status
                 */
-               if (!(rmp->mp_flags & ZOMBIE))
+               if (rmp->mp_flags & TOLD_PARENT)
                        real_cleanup(rmp);
 
                break;
@@ -909,7 +909,7 @@ message *m_ptr;
                /* Clean up if the parent has collected the exit
                 * status
                 */
-               if (!(rmp->mp_flags & ZOMBIE))
+               if (rmp->mp_flags & TOLD_PARENT)
                        real_cleanup(rmp);
 
                break;
index 500c60a26517e1d0398bba17356b138181a88382..047de24af29115a990bcb0cc7facae3293ae2214 100644 (file)
@@ -84,6 +84,7 @@ EXTERN struct mproc {
 #define PRIV_PROC      0x2000   /* system process, special privileges */
 #define PM_SIG_PENDING 0x4000  /* process got a signal while waiting for FS */
 #define PARTIAL_EXEC   0x8000  /* Process got a new map but no content */
+#define TOLD_PARENT   0x10000  /* Parent wait() completed, ZOMBIE off */
 
 #define NIL_MPROC ((struct mproc *) 0)
 
index 6332a12eff4f30e4243edaffa6b3421e3c4a3200..5dbeb18b845b95f483b443b3c86525a4e60147fe 100644 (file)
@@ -454,6 +454,8 @@ int signo;                  /* signal to send to process (1 to _NSIG) */
 #endif
   sigflags = rmp->mp_sigact[signo].sa_flags;
   if (sigismember(&rmp->mp_catch, signo)) {
+       /* Stop process from running before we do stack calculations. */
+       sys_nice(rmp->mp_endpoint, PRIO_STOP);
        if (rmp->mp_flags & SIGSUSPENDED)
                rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask2;
        else