summaryrefslogtreecommitdiff
path: root/win32/win32.c
diff options
context:
space:
mode:
authorTomasz Konojacki <me@xenu.pl>2020-03-18 03:17:52 +0100
committerKarl Williamson <khw@cpan.org>2020-07-24 12:25:04 -0600
commit81295a42ad856da581d910c540f5bb7a18b8f7e2 (patch)
treef73be19818bd0eaafcb7c2af031ba3d61715cdb6 /win32/win32.c
parent924b0bfd9d159bece72423ebd5674d82284e0f5c (diff)
downloadperl-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.c11
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 */