aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-08-29 18:32:04 +0300
committerEli Zaretskii2013-08-29 18:32:04 +0300
commit3f940c5aa6fc1d03e6658cda5c440fb6bd75e4c5 (patch)
tree5729694efb5e29a00b9fad2f9c081d2198f3ccc9 /src
parent20de2834a594370b2f30fa55932c9de3da6150ed (diff)
downloademacs-3f940c5aa6fc1d03e6658cda5c440fb6bd75e4c5.tar.gz
emacs-3f940c5aa6fc1d03e6658cda5c440fb6bd75e4c5.zip
A possible fix for bug #14333 with hanging at exit on MS-Windows.
src/w32.c (term_winsock): Call release_listen_threads before calling WSACleanup. (_sys_wait_accept): Wait for accept event in a loop with a finite timeout, instead of waiting indefinitely. Will hopefully avoid hanging during exit because WSACleanup deadlocks waiting for the event object to be released. src/w32proc.c (release_listen_threads): New function, signals all the reader threads that listen for connections to stop waiting. src/w32.h (release_listen_threads): Add prototype.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/w32.c8
-rw-r--r--src/w32.h1
-rw-r--r--src/w32proc.c12
4 files changed, 34 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a020c1278e3..0a24427f683 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12013-08-29 Eli Zaretskii <eliz@gnu.org>
2
3 * w32.c (term_winsock): Call release_listen_threads before calling
4 WSACleanup.
5 (_sys_wait_accept): Wait for accept event in a loop with a finite
6 timeout, instead of waiting indefinitely. Will hopefully avoid
7 hanging during exit because WSACleanup deadlocks waiting for the
8 event object to be released. (Bug#14333)
9
10 * w32proc.c (release_listen_threads): New function, signals all
11 the reader threads that listen for connections to stop waiting.
12
13 * w32.h (release_listen_threads): Add prototype.
14
12013-08-29 Dmitry Antipov <dmantipov@yandex.ru> 152013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
2 16
3 * alloc.c (Fmake_marker, build_marker): Zero need_adjustment 17 * alloc.c (Fmake_marker, build_marker): Zero need_adjustment
diff --git a/src/w32.c b/src/w32.c
index 05a3fde97ce..1dcf46b5f4b 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -6092,6 +6092,7 @@ term_winsock (void)
6092{ 6092{
6093 if (winsock_lib != NULL && winsock_inuse == 0) 6093 if (winsock_lib != NULL && winsock_inuse == 0)
6094 { 6094 {
6095 release_listen_threads ();
6095 /* Not sure what would cause WSAENETDOWN, or even if it can happen 6096 /* Not sure what would cause WSAENETDOWN, or even if it can happen
6096 after WSAStartup returns successfully, but it seems reasonable 6097 after WSAStartup returns successfully, but it seems reasonable
6097 to allow unloading winsock anyway in that case. */ 6098 to allow unloading winsock anyway in that case. */
@@ -7076,7 +7077,12 @@ _sys_wait_accept (int fd)
7076 rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT); 7077 rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
7077 if (rc != SOCKET_ERROR) 7078 if (rc != SOCKET_ERROR)
7078 { 7079 {
7079 rc = WaitForSingleObject (hEv, INFINITE); 7080 do {
7081 rc = WaitForSingleObject (hEv, 500);
7082 Sleep (5);
7083 } while (rc == WAIT_TIMEOUT
7084 && cp->status != STATUS_READ_ERROR
7085 && cp->char_avail);
7080 pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0); 7086 pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
7081 if (rc == WAIT_OBJECT_0) 7087 if (rc == WAIT_OBJECT_0)
7082 cp->status = STATUS_READ_SUCCEEDED; 7088 cp->status = STATUS_READ_SUCCEEDED;
diff --git a/src/w32.h b/src/w32.h
index 9c1f1efa699..32d0fdbe3cf 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -163,6 +163,7 @@ extern void reset_standard_handles (int in, int out,
163/* Return the string resource associated with KEY of type TYPE. */ 163/* Return the string resource associated with KEY of type TYPE. */
164extern LPBYTE w32_get_resource (char * key, LPDWORD type); 164extern LPBYTE w32_get_resource (char * key, LPDWORD type);
165 165
166extern void release_listen_threads (void);
166extern void init_ntproc (int); 167extern void init_ntproc (int);
167extern void term_ntproc (int); 168extern void term_ntproc (int);
168extern void globals_of_w32 (void); 169extern void globals_of_w32 (void);
diff --git a/src/w32proc.c b/src/w32proc.c
index 54316a6f80f..dabaa62f71c 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -990,6 +990,18 @@ find_child_pid (DWORD pid)
990 return NULL; 990 return NULL;
991} 991}
992 992
993void
994release_listen_threads (void)
995{
996 int i;
997
998 for (i = child_proc_count - 1; i >= 0; i--)
999 {
1000 if (CHILD_ACTIVE (&child_procs[i])
1001 && (fd_info[child_procs[i].fd].flags & FILE_LISTEN))
1002 child_procs[i].status = STATUS_READ_ERROR;
1003 }
1004}
993 1005
994/* Thread proc for child process and socket reader threads. Each thread 1006/* Thread proc for child process and socket reader threads. Each thread
995 is normally blocked until woken by select() to check for input by 1007 is normally blocked until woken by select() to check for input by