emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/process.c


From: Kim F. Storm
Subject: [Emacs-diffs] Changes to emacs/src/process.c
Date: Thu, 01 Jun 2006 14:08:25 +0000

Index: emacs/src/process.c
diff -u emacs/src/process.c:1.482 emacs/src/process.c:1.483
--- emacs/src/process.c:1.482   Wed May 31 08:58:02 2006
+++ emacs/src/process.c Thu Jun  1 14:08:25 2006
@@ -778,6 +778,16 @@
   return proc;
 }
 
+
+#ifdef SIGCHLD
+/* Fdelete_process promises to immediately forget about the process, but in
+   reality, Emacs needs to remember those processes until they have been
+   treated by sigchld_handler; otherwise this handler would consider the
+   process as being synchronous and say that the synchronous process is
+   dead.  */
+static Lisp_Object deleted_pid_list;
+#endif
+
 DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
        doc: /* Delete PROCESS: kill it and forget about it immediately.
 PROCESS may be a process, a buffer, the name of a process or buffer, or
@@ -799,12 +809,31 @@
     }
   else if (XINT (p->infd) >= 0)
     {
-      Fkill_process (process, Qnil);
-      /* Do this now, since remove_process will make sigchld_handler do 
nothing.  */
-      p->status
-       = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
-      XSETINT (p->tick, ++process_tick);
-      status_notify (p);
+#ifdef SIGCHLD
+      Lisp_Object symbol;
+
+      /* No problem storing the pid here, as it is still in Vprocess_alist.  */
+      deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+                               /* GC treated elements set to nil.  */
+                               Fdelq (Qnil, deleted_pid_list));
+      /* If the process has already signaled, remove it from the list.  */
+      if (p->raw_status_new)
+       update_status (p);
+      symbol = p->status;
+      if (CONSP (p->status))
+       symbol = XCAR (p->status);
+      if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
+       Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+      else
+#endif
+       {
+         Fkill_process (process, Qnil);
+         /* Do this now, since remove_process will make sigchld_handler do 
nothing.  */
+         p->status
+           = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
+         XSETINT (p->tick, ++process_tick);
+         status_notify (p);
+       }
     }
   remove_process (process);
   return Qnil;
@@ -6335,6 +6364,7 @@
    ** Malloc WARNING: This should never call malloc either directly or
    indirectly; if it does, that is a bug  */
 
+#ifdef SIGCHLD
 SIGTYPE
 sigchld_handler (signo)
      int signo;
@@ -6392,6 +6422,15 @@
 
       /* Find the process that signaled us, and record its status.  */
 
+      /* The process can have been deleted by Fdelete_process.  */
+      tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
+      if (!NILP (tail))
+       {
+         Fsetcar (tail, Qnil);
+         goto sigchld_end_of_loop;
+       }
+
+      /* Otherwise, if it is asynchronous, it is in Vprocess_alist.  */
       p = 0;
       for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
        {
@@ -6443,8 +6482,8 @@
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
-       /* There was no asynchronous process found for that id.  Check
-          if we have a synchronous process.  */
+      /* There was no asynchronous process found for that pid: we have
+        a synchronous process.  */
       else
        {
          synch_process_alive = 0;
@@ -6461,6 +6500,9 @@
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
+    sigchld_end_of_loop:
+      ;
+
       /* On some systems, we must return right away.
         If any more processes want to signal us, we will
         get another signal.
@@ -6477,6 +6519,7 @@
 #endif /* USG, but not HPUX with WNOHANG */
     }
 }
+#endif /* SIGCHLD */
 
 
 static Lisp_Object
@@ -6862,6 +6905,9 @@
   FD_SET (0, &input_wait_mask);
 
   Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+  deleted_pid_list = Qnil;
+#endif
   for (i = 0; i < MAXDESC; i++)
     {
       chan_process[i] = Qnil;
@@ -7000,6 +7046,9 @@
   staticpro (&Qlast_nonmenu_event);
 
   staticpro (&Vprocess_alist);
+#ifdef SIGCHLD
+  staticpro (&deleted_pid_list);
+#endif
 
   DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
               doc: /* *Non-nil means delete processes immediately when they 
exit.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]