diff options
Diffstat (limited to 'src/w32proc.c')
| -rw-r--r-- | src/w32proc.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/w32proc.c b/src/w32proc.c index 8bf57602927..3f3e97c77a0 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -803,6 +803,48 @@ new_child (void) | |||
| 803 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) | 803 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) |
| 804 | goto Initialize; | 804 | goto Initialize; |
| 805 | if (child_proc_count == MAX_CHILDREN) | 805 | if (child_proc_count == MAX_CHILDREN) |
| 806 | { | ||
| 807 | int i = 0; | ||
| 808 | child_process *dead_cp = NULL; | ||
| 809 | |||
| 810 | DebPrint (("new_child: No vacant slots, looking for dead processes\n")); | ||
| 811 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | ||
| 812 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) | ||
| 813 | { | ||
| 814 | DWORD status = 0; | ||
| 815 | |||
| 816 | if (!GetExitCodeProcess (cp->procinfo.hProcess, &status)) | ||
| 817 | { | ||
| 818 | DebPrint (("new_child.GetExitCodeProcess: error %lu for PID %lu\n", | ||
| 819 | GetLastError (), cp->procinfo.dwProcessId)); | ||
| 820 | status = STILL_ACTIVE; | ||
| 821 | } | ||
| 822 | if (status != STILL_ACTIVE | ||
| 823 | || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) | ||
| 824 | { | ||
| 825 | DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n", | ||
| 826 | cp->procinfo.dwProcessId, cp->fd)); | ||
| 827 | CloseHandle (cp->procinfo.hProcess); | ||
| 828 | cp->procinfo.hProcess = NULL; | ||
| 829 | CloseHandle (cp->procinfo.hThread); | ||
| 830 | cp->procinfo.hThread = NULL; | ||
| 831 | /* Free up to 2 dead slots at a time, so that if we | ||
| 832 | have a lot of them, they will eventually all be | ||
| 833 | freed when the tornado ends. */ | ||
| 834 | if (i == 0) | ||
| 835 | dead_cp = cp; | ||
| 836 | else | ||
| 837 | break; | ||
| 838 | i++; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | if (dead_cp) | ||
| 842 | { | ||
| 843 | cp = dead_cp; | ||
| 844 | goto Initialize; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | if (child_proc_count == MAX_CHILDREN) | ||
| 806 | return NULL; | 848 | return NULL; |
| 807 | cp = &child_procs[child_proc_count++]; | 849 | cp = &child_procs[child_proc_count++]; |
| 808 | 850 | ||
| @@ -979,8 +1021,9 @@ reader_thread (void *arg) | |||
| 979 | read-ahead has completed, whether successfully or not. */ | 1021 | read-ahead has completed, whether successfully or not. */ |
| 980 | if (!SetEvent (cp->char_avail)) | 1022 | if (!SetEvent (cp->char_avail)) |
| 981 | { | 1023 | { |
| 982 | DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n", | 1024 | DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", |
| 983 | GetLastError (), cp->fd)); | 1025 | (DWORD_PTR)cp->char_avail, GetLastError (), |
| 1026 | cp->fd, cp->pid)); | ||
| 984 | return 1; | 1027 | return 1; |
| 985 | } | 1028 | } |
| 986 | 1029 | ||
| @@ -2008,7 +2051,7 @@ count_children: | |||
| 2008 | /* Some child_procs might be sockets; ignore them. Also some | 2051 | /* Some child_procs might be sockets; ignore them. Also some |
| 2009 | children may have died already, but we haven't finished reading | 2052 | children may have died already, but we haven't finished reading |
| 2010 | the process output; ignore them too. */ | 2053 | the process output; ignore them too. */ |
| 2011 | if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess | 2054 | if ((CHILD_ACTIVE (cp) && cp->procinfo.hProcess) |
| 2012 | && (cp->fd < 0 | 2055 | && (cp->fd < 0 |
| 2013 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 | 2056 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 |
| 2014 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) | 2057 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) |