-
Notifications
You must be signed in to change notification settings - Fork 559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
close($pipe_read_fh) hangs on Windows if another process is in read of same handle #19963
Labels
distro-mswin32
Win32
This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925
Comments
Leont
added
distro-mswin32
Win32
This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925
and removed
Needs Triage
labels
Jul 18, 2022
xenu
added a commit
to xenu/perl5
that referenced
this issue
Mar 10, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43) Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
xenu
added a commit
to xenu/perl5
that referenced
this issue
Mar 10, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
This PR will fix it: #20922 |
xenu
added a commit
to xenu/perl5
that referenced
this issue
Mar 17, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
xenu
added a commit
to xenu/perl5
that referenced
this issue
Mar 17, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
xenu
added a commit
that referenced
this issue
Mar 17, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes #19963) - _dup2 properly closes an overwritten socket (fixes #20920)
pjacklam
pushed a commit
to pjacklam/perl5
that referenced
this issue
May 20, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
pjacklam
pushed a commit
to pjacklam/perl5
that referenced
this issue
May 20, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
khwilliamson
pushed a commit
to khwilliamson/perl5
that referenced
this issue
Jul 10, 2023
_close() on an fd calls CloseHandle(), which is illegal if the fd contains a socket handle. We previously worked around this by having our own close(), which called closesocket() before calling _close() (e601c43). Amusingly, the author of that solution thought it's just a temporary workaround: /* * close RTL fd while respecting sockets * added as temporary measure until PerlIO has real * Win32 native layer * -- BKS, 11-11-2000 */ To make it thread-safe, we had to manipulate the internals of file descriptors, which kept changing (b47a847). Unfortunately, the C runtime has been rewritten and it no longer exposes them at all. We had to disable the thread-safety fix in Visual C++ 2015 builds (1f664ef). It also wouldn't work with MinGW configured to use UCRT. This commit introduces a new solution: we inject a socket-aware version of CloseHandle() into the C runtime library. Hopefully, this will be less fragile. This also fixes a few issues that the original solution didn't: - Closing a busy pipe doesn't cause a deadlock (fixes Perl#19963) - _dup2 properly closes an overwritten socket (fixes Perl#20920)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
distro-mswin32
Win32
This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925
This is a bug report for perl from noah@leadboat.com,
generated with the help of perlbug 1.42 running under perl 5.32.1.
Steps to Reproduce
Test program:
Expected behavior
I expected to see a line saying "parent exit", but the last output line
started with "before close". Setting
USE_WORKAROUND=1
in the environmentmakes the program reach "parent exit", achieving that expectation. I
distilled the test program from cpan-authors/IPC-Run#77.
Non-debug stack trace of hang
I think frame 6 is actually in my_close(), and the lack of debug symbols makes
that not show up here. win32_socket() is immediately before my_close() in the
source code.
Possible fixes
This trouble arises because my_close() assumes closesocket() will always
report
WSAENOTSOCK
for a non-socket. The first paragraph of the closesocketdocumentation remarks says not to rely on that. A robust fix would be to
maintain a data structure recording the FDs Perl has assigned to sockets, then
call closesocket() only for FDs appearing therein. One alternative would be
to use strategies like https://stackoverflow.com/q/50979090 to evaluate
whether a descriptor is a socket. That alternative may be simpler or more
efficient, but it's harder to cite API documentation supporting an expectation
that it will continue to work.
Perl configuration
The text was updated successfully, but these errors were encountered: