summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2013-08-29 18:32:04 +0300
committerEli Zaretskii <eliz@gnu.org>2013-08-29 18:32:04 +0300
commit3f940c5aa6fc1d03e6658cda5c440fb6bd75e4c5 (patch)
tree5729694efb5e29a00b9fad2f9c081d2198f3ccc9 /src
parent20de2834a594370b2f30fa55932c9de3da6150ed (diff)
downloademacs-3f940c5aa6fc1d03e6658cda5c440fb6bd75e4c5.tar.gz
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 @@
+2013-08-29 Eli Zaretskii <eliz@gnu.org>
+
+ * 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. (Bug#14333)
+
+ * w32proc.c (release_listen_threads): New function, signals all
+ the reader threads that listen for connections to stop waiting.
+
+ * w32.h (release_listen_threads): Add prototype.
+
2013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
* 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)
{
if (winsock_lib != NULL && winsock_inuse == 0)
{
+ release_listen_threads ();
/* Not sure what would cause WSAENETDOWN, or even if it can happen
after WSAStartup returns successfully, but it seems reasonable
to allow unloading winsock anyway in that case. */
@@ -7076,7 +7077,12 @@ _sys_wait_accept (int fd)
rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
if (rc != SOCKET_ERROR)
{
- rc = WaitForSingleObject (hEv, INFINITE);
+ do {
+ rc = WaitForSingleObject (hEv, 500);
+ Sleep (5);
+ } while (rc == WAIT_TIMEOUT
+ && cp->status != STATUS_READ_ERROR
+ && cp->char_avail);
pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
if (rc == WAIT_OBJECT_0)
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,
/* Return the string resource associated with KEY of type TYPE. */
extern LPBYTE w32_get_resource (char * key, LPDWORD type);
+extern void release_listen_threads (void);
extern void init_ntproc (int);
extern void term_ntproc (int);
extern 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)
return NULL;
}
+void
+release_listen_threads (void)
+{
+ int i;
+
+ for (i = child_proc_count - 1; i >= 0; i--)
+ {
+ if (CHILD_ACTIVE (&child_procs[i])
+ && (fd_info[child_procs[i].fd].flags & FILE_LISTEN))
+ child_procs[i].status = STATUS_READ_ERROR;
+ }
+}
/* Thread proc for child process and socket reader threads. Each thread
is normally blocked until woken by select() to check for input by