diff options
author | Tomasz Konojacki <me@xenu.pl> | 2020-03-18 03:17:52 +0100 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2020-07-24 12:25:04 -0600 |
commit | 81295a42ad856da581d910c540f5bb7a18b8f7e2 (patch) | |
tree | f73be19818bd0eaafcb7c2af031ba3d61715cdb6 /win32/win32.c | |
parent | 924b0bfd9d159bece72423ebd5674d82284e0f5c (diff) | |
download | perl-81295a42ad856da581d910c540f5bb7a18b8f7e2.tar.gz |
win32.c: rework the waitpid(-1, WNOHANG) fix
Oops! While 08e55ec5e3ef6d6c040c0dc8bdec7d59f76bfbe8 made
waitpid(-1, WNOHANG) not segfault, it introduced another problem:
when retry == 1, MsgWaitForMultipleObjects() will sometimes be
called with a very large timeout due to unsigned integer overflow.
This is *exactly* the same problem that the comment above the loop
warns about.
Diffstat (limited to 'win32/win32.c')
-rw-r--r-- | win32/win32.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/win32/win32.c b/win32/win32.c index e3769b5272..9719f14fa3 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2239,7 +2239,6 @@ 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,13 +2261,12 @@ 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 || retry) { + while (ticks.ft_i64 <= endtime) { /* 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) { @@ -2284,7 +2282,12 @@ 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; + + /* retry */ + if (ticks.ft_i64 > endtime) + endtime = ticks.ft_i64; + + continue; } else { /* Not timeout or message - one of handles is ready */ |