Skip to content

Commit

Permalink
win32.c: rework the waitpid(-1, WNOHANG) fix
Browse files Browse the repository at this point in the history
Oops! While 08e55ec 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.
  • Loading branch information
xenu authored and khwilliamson committed Jul 24, 2020
1 parent 924b0bf commit 81295a4
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions win32/win32.c
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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 */
Expand Down

0 comments on commit 81295a4

Please sign in to comment.