]> code.delx.au - gnu-emacs/commitdiff
More robust creation of a subprocess, attempt to solve bug #13546.
authorEli Zaretskii <eliz@gnu.org>
Wed, 13 Feb 2013 17:04:30 +0000 (19:04 +0200)
committerEli Zaretskii <eliz@gnu.org>
Wed, 13 Feb 2013 17:04:30 +0000 (19:04 +0200)
 src/w32proc.c (new_child): If no vacant slots are found in
 child_procs[], make another pass looking for slots whose process
 has exited or died.

src/ChangeLog
src/w32proc.c

index 358f25b40f9cd99a12d75fa41decf073d2f8755e..e1b8a23e6b2d94418062bc8fe50a98c02c3b5aaa 100644 (file)
@@ -1,5 +1,9 @@
 2013-02-13  Eli Zaretskii  <eliz@gnu.org>
 
+       * w32proc.c (new_child): If no vacant slots are found in
+       child_procs[], make another pass looking for slots whose process
+       has exited or died.  (Bug#13546)
+
        * w32.c (sys_pipe): When failing due to file descriptors above
        MAXDESC, set errno to EMFILE.
        (_sys_read_ahead): Update cp->status when failing to read serial
index 8c09a1b1bebb0df8d8a1d23caa8d7357454c0289..1e72d41e16b2ac7902b7807a991edf69f70ce615 100644 (file)
@@ -797,6 +797,33 @@ new_child (void)
   for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
     if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL)
       goto Initialize;
+  if (child_proc_count == MAX_CHILDREN)
+    {
+      DebPrint (("new_child: No vacant slots, looking for dead processes\n"));
+      for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
+       if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
+         {
+           DWORD status = 0;
+
+           if (!GetExitCodeProcess (cp->procinfo.hProcess, &status))
+             {
+               DebPrint (("new_child.GetExitCodeProcess: error %lu for PID %lu\n",
+                          GetLastError (), cp->procinfo.dwProcessId));
+               status = STILL_ACTIVE;
+             }
+           if (status != STILL_ACTIVE
+               || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0)
+             {
+               DebPrint (("new_child: Freeing slot of dead process %d\n",
+                          cp->procinfo.dwProcessId));
+               CloseHandle (cp->procinfo.hProcess);
+               cp->procinfo.hProcess = NULL;
+               CloseHandle (cp->procinfo.hThread);
+               cp->procinfo.hThread = NULL;
+               goto Initialize;
+             }
+         }
+    }
   if (child_proc_count == MAX_CHILDREN)
     return NULL;
   cp = &child_procs[child_proc_count++];