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.
This commit is contained in:
parent
20de2834a5
commit
3f940c5aa6
4 changed files with 34 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue