aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-02-17 20:17:34 +0200
committerEli Zaretskii2013-02-17 20:17:34 +0200
commitae11bda519726c8619f687645138f913b1027be3 (patch)
tree50f479da0a7572017d55baf6eb017ef6012c58f4 /src
parentfd80c659d21fa9f42ae0f862fb51580afa63fdd0 (diff)
downloademacs-ae11bda519726c8619f687645138f913b1027be3.tar.gz
emacs-ae11bda519726c8619f687645138f913b1027be3.zip
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/ChangeLog12
-rw-r--r--src/w32proc.c70
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 @@
12013-02-17 Eli Zaretskii <eliz@gnu.org> 12013-02-17 Eli Zaretskii <eliz@gnu.org>
2 2
3 * w32proc.c (new_child): Remove the loop that attempted to salvage
4 slots of dead processes.
5 (new_child, delete_child, find_child_pid): Don't insist on
6 procinfo.hProcess be NULL for a process slot to be considered
7 inactive, or be non-NULL to be considered active.
8 (reader_thread): Don't set the FILE_AT_EOF flag of a file
9 descriptor if the corresponding child was deleted and its
10 char_avail handle is NULL.
11 (reap_subprocess): Don't reset the FILE_AT_EOF flag. (Bug#13546)
12 (sys_select): Don't pass a NULL process handle to
13 WaitForMultipleObjects. (Bug#13735)
14
3 * xdisp.c (x_draw_vertical_border): For a window that is neither 15 * xdisp.c (x_draw_vertical_border): For a window that is neither
4 the leftmost nor the rightmost, redraw both the left and the right 16 the leftmost nor the rightmost, redraw both the left and the right
5 vertical borders. (Bug#13723) 17 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)
795 DWORD id; 795 DWORD id;
796 796
797 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) 797 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
798 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) 798 if (!CHILD_ACTIVE (cp))
799 goto Initialize; 799 goto Initialize;
800 if (child_proc_count == MAX_CHILDREN) 800 if (child_proc_count == MAX_CHILDREN)
801 {
802 int i = 0;
803 child_process *dead_cp = NULL;
804
805 DebPrint (("new_child: No vacant slots, looking for dead processes\n"));
806 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
807 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
808 {
809 DWORD status = 0;
810
811 if (!GetExitCodeProcess (cp->procinfo.hProcess, &status))
812 {
813 DebPrint (("new_child.GetExitCodeProcess: error %lu for PID %lu\n",
814 GetLastError (), cp->procinfo.dwProcessId));
815 status = STILL_ACTIVE;
816 }
817 if (status != STILL_ACTIVE
818 || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0)
819 {
820 DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n",
821 cp->procinfo.dwProcessId, cp->fd));
822 CloseHandle (cp->procinfo.hProcess);
823 cp->procinfo.hProcess = NULL;
824 CloseHandle (cp->procinfo.hThread);
825 cp->procinfo.hThread = NULL;
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 break;
833 i++;
834 }
835 }
836 if (dead_cp)
837 {
838 cp = dead_cp;
839 goto Initialize;
840 }
841 }
842 if (child_proc_count == MAX_CHILDREN)
843 return NULL; 801 return NULL;
844 cp = &child_procs[child_proc_count++]; 802 cp = &child_procs[child_proc_count++];
845 803
@@ -894,7 +852,7 @@ delete_child (child_process *cp)
894 if (fd_info[i].cp == cp) 852 if (fd_info[i].cp == cp)
895 emacs_abort (); 853 emacs_abort ();
896 854
897 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) 855 if (!CHILD_ACTIVE (cp))
898 return; 856 return;
899 857
900 /* reap thread if necessary */ 858 /* reap thread if necessary */
@@ -938,8 +896,7 @@ delete_child (child_process *cp)
938 if (cp == child_procs + child_proc_count - 1) 896 if (cp == child_procs + child_proc_count - 1)
939 { 897 {
940 for (i = child_proc_count-1; i >= 0; i--) 898 for (i = child_proc_count-1; i >= 0; i--)
941 if (CHILD_ACTIVE (&child_procs[i]) 899 if (CHILD_ACTIVE (&child_procs[i]))
942 || child_procs[i].procinfo.hProcess != NULL)
943 { 900 {
944 child_proc_count = i + 1; 901 child_proc_count = i + 1;
945 break; 902 break;
@@ -956,8 +913,7 @@ find_child_pid (DWORD pid)
956 child_process *cp; 913 child_process *cp;
957 914
958 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) 915 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
959 if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess != NULL) 916 if (CHILD_ACTIVE (cp) && pid == cp->pid)
960 && pid == cp->pid)
961 return cp; 917 return cp;
962 return NULL; 918 return NULL;
963} 919}
@@ -990,17 +946,6 @@ reader_thread (void *arg)
990 else 946 else
991 rc = _sys_read_ahead (cp->fd); 947 rc = _sys_read_ahead (cp->fd);
992 948
993 if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess && cp->fd >= 0)
994 {
995 /* Somebody already called delete_child on this child, since
996 only delete_child zeroes out cp->char_avail. This means
997 no one will read from cp->fd and will not set the
998 FILE_AT_EOF flag, therefore preventing sys_select from
999 noticing that the process died. Set the flag here
1000 instead. */
1001 fd_info[cp->fd].flags |= FILE_AT_EOF;
1002 }
1003
1004 /* The name char_avail is a misnomer - it really just means the 949 /* The name char_avail is a misnomer - it really just means the
1005 read-ahead has completed, whether successfully or not. */ 950 read-ahead has completed, whether successfully or not. */
1006 if (!SetEvent (cp->char_avail)) 951 if (!SetEvent (cp->char_avail))
@@ -1168,11 +1113,6 @@ reap_subprocess (child_process *cp)
1168 register_child has not been called. */ 1113 register_child has not been called. */
1169 if (cp->fd == -1) 1114 if (cp->fd == -1)
1170 delete_child (cp); 1115 delete_child (cp);
1171 else
1172 {
1173 /* Reset the flag set by reader_thread. */
1174 fd_info[cp->fd].flags &= ~FILE_AT_EOF;
1175 }
1176} 1116}
1177 1117
1178/* Wait for any of our existing child processes to die 1118/* Wait for any of our existing child processes to die
@@ -1957,7 +1897,7 @@ count_children:
1957 /* Some child_procs might be sockets; ignore them. Also some 1897 /* Some child_procs might be sockets; ignore them. Also some
1958 children may have died already, but we haven't finished reading 1898 children may have died already, but we haven't finished reading
1959 the process output; ignore them too. */ 1899 the process output; ignore them too. */
1960 if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess) 1900 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
1961 && (cp->fd < 0 1901 && (cp->fd < 0
1962 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 1902 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
1963 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) 1903 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)