aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-02-15 11:41:31 +0200
committerEli Zaretskii2013-02-15 11:41:31 +0200
commitef862e206a28f6618048c8b28413fa8f9c135c61 (patch)
tree268021369bcc27a23f840634815215bd6d0d6def /src
parentbcf7fe2aeff7e3aacbfae08ca6001f7615a06709 (diff)
downloademacs-ef862e206a28f6618048c8b28413fa8f9c135c61.tar.gz
emacs-ef862e206a28f6618048c8b28413fa8f9c135c61.zip
Allow deleted processes to be reaped by SIGCHLD handler on MS-Windows.
src/w32proc.c (new_child): Free up to 2 slots of dead processes at a time. Improve diagnostics in DebPrint. (reader_thread): If cp->char_avail is NULL, set the FILE_AT_EOF flag, so that sys_select could have a chance of noticing that this process is dead, and call a SIGCHLD handler for it. Improve diagnostics in DebPrint. (reap_subprocess): Reset the FILE_AT_EOF flag set by reader_thread. (sys_select): Watch a process whose procinfo.hProcess is non-NULL even if its char_avail is NULL. Allows to reap subprocesses that were forcibly deleted by delete-process. (Bug#13546)
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/w32proc.c42
2 files changed, 48 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 47a55535870..f4bee9f0905 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,17 @@
12013-02-15 Eli Zaretskii <eliz@gnu.org> 12013-02-15 Eli Zaretskii <eliz@gnu.org>
2 2
3 * w32proc.c (new_child): Free up to 2 slots of dead processes at a
4 time. Improve diagnostics in DebPrint.
5 (reader_thread): If cp->char_avail is NULL, set the FILE_AT_EOF
6 flag, so that sys_select could have a chance of noticing that this
7 process is dead, and call a SIGCHLD handler for it. Improve
8 diagnostics in DebPrint.
9 (reap_subprocess): Reset the FILE_AT_EOF flag set by
10 reader_thread.
11 (sys_select): Watch a process whose procinfo.hProcess is non-NULL
12 even if its char_avail is NULL. Allows to reap subprocesses that
13 were forcibly deleted by delete-process. (Bug#13546)
14
3 * w32.c (sys_socket, sys_bind, sys_connect, sys_gethostname) 15 * w32.c (sys_socket, sys_bind, sys_connect, sys_gethostname)
4 (sys_gethostbyname, sys_getservbyname, sys_getpeername) 16 (sys_gethostbyname, sys_getservbyname, sys_getpeername)
5 (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) 17 (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname)
diff --git a/src/w32proc.c b/src/w32proc.c
index 1e72d41e16b..e9860a66468 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -799,6 +799,9 @@ new_child (void)
799 goto Initialize; 799 goto Initialize;
800 if (child_proc_count == MAX_CHILDREN) 800 if (child_proc_count == MAX_CHILDREN)
801 { 801 {
802 int i = 0;
803 child_process *dead_cp;
804
802 DebPrint (("new_child: No vacant slots, looking for dead processes\n")); 805 DebPrint (("new_child: No vacant slots, looking for dead processes\n"));
803 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) 806 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
804 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) 807 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
@@ -814,13 +817,23 @@ new_child (void)
814 if (status != STILL_ACTIVE 817 if (status != STILL_ACTIVE
815 || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) 818 || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0)
816 { 819 {
817 DebPrint (("new_child: Freeing slot of dead process %d\n", 820 DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n",
818 cp->procinfo.dwProcessId)); 821 cp->procinfo.dwProcessId, cp->fd));
819 CloseHandle (cp->procinfo.hProcess); 822 CloseHandle (cp->procinfo.hProcess);
820 cp->procinfo.hProcess = NULL; 823 cp->procinfo.hProcess = NULL;
821 CloseHandle (cp->procinfo.hThread); 824 CloseHandle (cp->procinfo.hThread);
822 cp->procinfo.hThread = NULL; 825 cp->procinfo.hThread = NULL;
823 goto Initialize; 826 /* Free up to 2 dead slots at a time, so that if we
827 have a lot of them, they will eventually all be
828 freed when the tornado ends. */
829 if (i == 0)
830 dead_cp = cp;
831 else
832 {
833 cp = dead_cp;
834 goto Initialize;
835 }
836 i++;
824 } 837 }
825 } 838 }
826 } 839 }
@@ -975,12 +988,24 @@ reader_thread (void *arg)
975 else 988 else
976 rc = _sys_read_ahead (cp->fd); 989 rc = _sys_read_ahead (cp->fd);
977 990
991 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess && cp->fd >= 0)
992 {
993 /* Somebody already called delete_child on this child, since
994 only delete_child zeroes out cp->char_avail. This means
995 no one will read from cp->fd and will not set the
996 FILE_AT_EOF flag, therefore preventing sys_select from
997 noticing that the process died. Set the flag here
998 instead. */
999 fd_info[cp->fd].flags |= FILE_AT_EOF;
1000 }
1001
978 /* The name char_avail is a misnomer - it really just means the 1002 /* The name char_avail is a misnomer - it really just means the
979 read-ahead has completed, whether successfully or not. */ 1003 read-ahead has completed, whether successfully or not. */
980 if (!SetEvent (cp->char_avail)) 1004 if (!SetEvent (cp->char_avail))
981 { 1005 {
982 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n", 1006 DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n",
983 GetLastError (), cp->fd)); 1007 (DWORD_PTR)cp->char_avail, GetLastError (),
1008 cp->fd, cp->pid));
984 return 1; 1009 return 1;
985 } 1010 }
986 1011
@@ -1141,6 +1166,11 @@ reap_subprocess (child_process *cp)
1141 register_child has not been called. */ 1166 register_child has not been called. */
1142 if (cp->fd == -1) 1167 if (cp->fd == -1)
1143 delete_child (cp); 1168 delete_child (cp);
1169 else
1170 {
1171 /* Reset the flag set by reader_thread. */
1172 fd_info[cp->fd].flags &= ~FILE_AT_EOF;
1173 }
1144} 1174}
1145 1175
1146/* Wait for any of our existing child processes to die 1176/* Wait for any of our existing child processes to die
@@ -1925,7 +1955,7 @@ count_children:
1925 /* Some child_procs might be sockets; ignore them. Also some 1955 /* Some child_procs might be sockets; ignore them. Also some
1926 children may have died already, but we haven't finished reading 1956 children may have died already, but we haven't finished reading
1927 the process output; ignore them too. */ 1957 the process output; ignore them too. */
1928 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess 1958 if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess)
1929 && (cp->fd < 0 1959 && (cp->fd < 0
1930 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 1960 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
1931 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) 1961 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)