diff options
author | Tomasz Konojacki <me@xenu.pl> | 2019-11-10 07:14:01 +0100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2020-02-12 17:47:15 +0000 |
commit | b26c7c73a310fb5aacf2fbb5a13cae72ec5a8c9a (patch) | |
tree | 70b97a589c3e8e182c370421c6e67e4521b1990b | |
parent | 9fe9294d6c1f24ed271a08d4720e83958fe71278 (diff) | |
download | perl-b26c7c73a310fb5aacf2fbb5a13cae72ec5a8c9a.tar.gz |
win32: fix waitpid(-1, WNOHANG) segfault/panic
waitpid(-1, WNOHANG) would panic or segfault if called when the
thread's message queue is not empty.
Thanks to Erik Jezierski for the report and diagnosis.
[gh #16529]
(cherry picked from commit 08e55ec5e3ef6d6c040c0dc8bdec7d59f76bfbe8)
-rw-r--r-- | win32/win32.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/win32/win32.c b/win32/win32.c index 8104d864c2..0e199ac121 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2240,6 +2240,7 @@ win32_async_check(pTHX) DllExport DWORD win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD resultp) { + int retry = 0; /* We may need several goes at this - so compute when we stop */ FT_t ticks = {0}; unsigned __int64 endtime = timeout; @@ -2262,12 +2263,13 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result * from another process (msctf.dll doing IPC among its instances, VS debugger * causes msctf.dll to be loaded into Perl by kernel), see [perl #33096]. */ - while (ticks.ft_i64 <= endtime) { + while (ticks.ft_i64 <= endtime || retry) { /* if timeout's type is lengthened, remember to split 64b timeout * into multiple non-infinity runs of MWFMO */ DWORD result = MsgWaitForMultipleObjects(count, handles, FALSE, (DWORD)(endtime - ticks.ft_i64), QS_POSTMESSAGE|QS_TIMER|QS_SENDMESSAGE); + retry = 0; if (resultp) *resultp = result; if (result == WAIT_TIMEOUT) { @@ -2283,6 +2285,7 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result if (result == WAIT_OBJECT_0 + count) { /* Message has arrived - check it */ (void)win32_async_check(aTHX); + retry = 1; } else { /* Not timeout or message - one of handles is ready */ |