summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2021-12-11 20:15:53 +0200
committerEli Zaretskii <eliz@gnu.org>2021-12-11 20:15:53 +0200
commita81669c69fda1a2d0d4238b8440145fb2aeb959f (patch)
treeef4f554f4505d9a5171f57878e2f38dea8d01cda /src/w32.c
parent8c50016b100ec2c548ec90131e0f5fb5f4ebb5c1 (diff)
downloademacs-a81669c69fda1a2d0d4238b8440145fb2aeb959f.tar.gz
emacs-a81669c69fda1a2d0d4238b8440145fb2aeb959f.tar.bz2
emacs-a81669c69fda1a2d0d4238b8440145fb2aeb959f.zip
Fix hang when deleting a pipe process
* src/w32.h (FILE_DONT_CLOSE): New flag. * src/w32.c (sys_close): Don't close descriptors used to read from the pipe process. Leave the FILE_DONT_CLOSE flag set in the descriptor's info. (register_aux_fd): Set the FILE_DONT_CLOSE flag in the descriptor's info. * src/w32proc.c (reader_thread): When exiting normally, close the file descriptor used to read from a pipe process. (Bug#52414)
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/w32.c b/src/w32.c
index 2b2f8aadf6b..1de148f0343 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -8548,7 +8548,7 @@ fcntl (int s, int cmd, int options)
int
sys_close (int fd)
{
- int rc;
+ int rc = -1;
if (fd < 0)
{
@@ -8603,14 +8603,31 @@ sys_close (int fd)
}
}
- if (fd >= 0 && fd < MAXDESC)
- fd_info[fd].flags = 0;
-
/* Note that sockets do not need special treatment here (at least on
NT and Windows 95 using the standard tcp/ip stacks) - it appears that
closesocket is equivalent to CloseHandle, which is to be expected
because socket handles are fully fledged kernel handles. */
- rc = _close (fd);
+ if (fd < MAXDESC)
+ {
+ if ((fd_info[fd].flags & FILE_DONT_CLOSE) == 0)
+ {
+ fd_info[fd].flags = 0;
+ rc = _close (fd);
+ }
+ else
+ {
+ /* We don't close here descriptors open by pipe processes
+ for reading from the pipe, because the reader thread
+ might be stuck in _sys_read_ahead, and then we will hang
+ here. If the reader thread exits normally, it will close
+ the descriptor; otherwise we will leave a zombie thread
+ hanging around. */
+ rc = 0;
+ /* Leave the flag set for the reader thread to close the
+ descriptor. */
+ fd_info[fd].flags = FILE_DONT_CLOSE;
+ }
+ }
return rc;
}
@@ -10898,6 +10915,7 @@ register_aux_fd (int infd)
}
fd_info[ infd ].cp = cp;
fd_info[ infd ].hnd = (HANDLE) _get_osfhandle (infd);
+ fd_info[ infd ].flags |= FILE_DONT_CLOSE;
}
#ifdef HAVE_GNUTLS