diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-02-17 20:17:34 +0200 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-02-17 20:17:34 +0200 |
commit | ae11bda519726c8619f687645138f913b1027be3 (patch) | |
tree | 50f479da0a7572017d55baf6eb017ef6012c58f4 /src | |
parent | fd80c659d21fa9f42ae0f862fb51580afa63fdd0 (diff) | |
download | emacs-ae11bda519726c8619f687645138f913b1027be3.tar.gz |
Fix bug #13735 with network streams on MS-Windows.
Revert changes to w32proc.c done since 2012-11-30T09:23:15Z!eliz@gnu.org.
Do NOT merge to trunk!
src/w32proc.c (new_child): Remove the loop that attempted to salvage
slots of dead processes.
(new_child, delete_child, find_child_pid): Don't insist on
procinfo.hProcess be NULL for a process slot to be considered
inactive, or be non-NULL to be considered active.
(reader_thread): Don't set the FILE_AT_EOF flag of a file
descriptor if the corresponding child was deleted and its
char_avail handle is NULL.
(reap_subprocess): Don't reset the FILE_AT_EOF flag.
(sys_select): Don't pass a NULL process handle to
WaitForMultipleObjects.
Fixes: debbugs:13735 debbugs:13546
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 12 | ||||
-rw-r--r-- | src/w32proc.c | 70 |
2 files changed, 17 insertions, 65 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 06207f6690e..4325d35adee 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,17 @@ 2013-02-17 Eli Zaretskii <eliz@gnu.org> + * w32proc.c (new_child): Remove the loop that attempted to salvage + slots of dead processes. + (new_child, delete_child, find_child_pid): Don't insist on + procinfo.hProcess be NULL for a process slot to be considered + inactive, or be non-NULL to be considered active. + (reader_thread): Don't set the FILE_AT_EOF flag of a file + descriptor if the corresponding child was deleted and its + char_avail handle is NULL. + (reap_subprocess): Don't reset the FILE_AT_EOF flag. (Bug#13546) + (sys_select): Don't pass a NULL process handle to + WaitForMultipleObjects. (Bug#13735) + * xdisp.c (x_draw_vertical_border): For a window that is neither the leftmost nor the rightmost, redraw both the left and the right vertical borders. (Bug#13723) diff --git a/src/w32proc.c b/src/w32proc.c index ca2096aaa9d..3b4522bf16b 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -795,51 +795,9 @@ new_child (void) DWORD id; for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) - if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) + if (!CHILD_ACTIVE (cp)) goto Initialize; if (child_proc_count == MAX_CHILDREN) - { - int i = 0; - child_process *dead_cp = NULL; - - 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, fd %d\n", - cp->procinfo.dwProcessId, cp->fd)); - CloseHandle (cp->procinfo.hProcess); - cp->procinfo.hProcess = NULL; - CloseHandle (cp->procinfo.hThread); - cp->procinfo.hThread = NULL; - /* Free up to 2 dead slots at a time, so that if we - have a lot of them, they will eventually all be - freed when the tornado ends. */ - if (i == 0) - dead_cp = cp; - else - break; - i++; - } - } - if (dead_cp) - { - cp = dead_cp; - goto Initialize; - } - } - if (child_proc_count == MAX_CHILDREN) return NULL; cp = &child_procs[child_proc_count++]; @@ -894,7 +852,7 @@ delete_child (child_process *cp) if (fd_info[i].cp == cp) emacs_abort (); - if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) + if (!CHILD_ACTIVE (cp)) return; /* reap thread if necessary */ @@ -938,8 +896,7 @@ delete_child (child_process *cp) if (cp == child_procs + child_proc_count - 1) { for (i = child_proc_count-1; i >= 0; i--) - if (CHILD_ACTIVE (&child_procs[i]) - || child_procs[i].procinfo.hProcess != NULL) + if (CHILD_ACTIVE (&child_procs[i])) { child_proc_count = i + 1; break; @@ -956,8 +913,7 @@ find_child_pid (DWORD pid) child_process *cp; for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) - if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess != NULL) - && pid == cp->pid) + if (CHILD_ACTIVE (cp) && pid == cp->pid) return cp; return NULL; } @@ -990,17 +946,6 @@ reader_thread (void *arg) else rc = _sys_read_ahead (cp->fd); - if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess && cp->fd >= 0) - { - /* Somebody already called delete_child on this child, since - only delete_child zeroes out cp->char_avail. This means - no one will read from cp->fd and will not set the - FILE_AT_EOF flag, therefore preventing sys_select from - noticing that the process died. Set the flag here - instead. */ - fd_info[cp->fd].flags |= FILE_AT_EOF; - } - /* The name char_avail is a misnomer - it really just means the read-ahead has completed, whether successfully or not. */ if (!SetEvent (cp->char_avail)) @@ -1168,11 +1113,6 @@ reap_subprocess (child_process *cp) register_child has not been called. */ if (cp->fd == -1) delete_child (cp); - else - { - /* Reset the flag set by reader_thread. */ - fd_info[cp->fd].flags &= ~FILE_AT_EOF; - } } /* Wait for any of our existing child processes to die @@ -1957,7 +1897,7 @@ count_children: /* Some child_procs might be sockets; ignore them. Also some children may have died already, but we haven't finished reading the process output; ignore them too. */ - if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess) + if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) |