Skip to content

Commit ae1f5af

Browse files
committed
win32.c: rework the waitpid(-1, WNOHANG) fix
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.
1 parent 2f07b2f commit ae1f5af

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

win32/win32.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,7 +2241,6 @@ win32_async_check(pTHX)
22412241
DllExport DWORD
22422242
win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD resultp)
22432243
{
2244-
int retry = 0;
22452244
/* We may need several goes at this - so compute when we stop */
22462245
FT_t ticks = {0};
22472246
unsigned __int64 endtime = timeout;
@@ -2264,13 +2263,12 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result
22642263
* from another process (msctf.dll doing IPC among its instances, VS debugger
22652264
* causes msctf.dll to be loaded into Perl by kernel), see [perl #33096].
22662265
*/
2267-
while (ticks.ft_i64 <= endtime || retry) {
2266+
while (ticks.ft_i64 <= endtime) {
22682267
/* if timeout's type is lengthened, remember to split 64b timeout
22692268
* into multiple non-infinity runs of MWFMO */
22702269
DWORD result = MsgWaitForMultipleObjects(count, handles, FALSE,
22712270
(DWORD)(endtime - ticks.ft_i64),
22722271
QS_POSTMESSAGE|QS_TIMER|QS_SENDMESSAGE);
2273-
retry = 0;
22742272
if (resultp)
22752273
*resultp = result;
22762274
if (result == WAIT_TIMEOUT) {
@@ -2286,7 +2284,12 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result
22862284
if (result == WAIT_OBJECT_0 + count) {
22872285
/* Message has arrived - check it */
22882286
(void)win32_async_check(aTHX);
2289-
retry = 1;
2287+
2288+
/* retry */
2289+
if (ticks.ft_i64 > endtime)
2290+
endtime = ticks.ft_i64;
2291+
2292+
continue;
22902293
}
22912294
else {
22922295
/* Not timeout or message - one of handles is ready */

0 commit comments

Comments
 (0)