summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Konojacki <me@xenu.pl>2019-11-10 07:14:01 +0100
committerSteve Hay <steve.m.hay@googlemail.com>2020-02-12 17:47:15 +0000
commitb26c7c73a310fb5aacf2fbb5a13cae72ec5a8c9a (patch)
tree70b97a589c3e8e182c370421c6e67e4521b1990b
parent9fe9294d6c1f24ed271a08d4720e83958fe71278 (diff)
downloadperl-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.c5
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 */