Skip to content

Commit 08e55ec

Browse files
xenukhwilliamson
authored andcommitted
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]
1 parent 9f26aea commit 08e55ec

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

win32/win32.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2240,6 +2240,7 @@ win32_async_check(pTHX)
22402240
DllExport DWORD
22412241
win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD resultp)
22422242
{
2243+
int retry = 0;
22432244
/* We may need several goes at this - so compute when we stop */
22442245
FT_t ticks = {0};
22452246
unsigned __int64 endtime = timeout;
@@ -2262,12 +2263,13 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result
22622263
* from another process (msctf.dll doing IPC among its instances, VS debugger
22632264
* causes msctf.dll to be loaded into Perl by kernel), see [perl #33096].
22642265
*/
2265-
while (ticks.ft_i64 <= endtime) {
2266+
while (ticks.ft_i64 <= endtime || retry) {
22662267
/* if timeout's type is lengthened, remember to split 64b timeout
22672268
* into multiple non-infinity runs of MWFMO */
22682269
DWORD result = MsgWaitForMultipleObjects(count, handles, FALSE,
22692270
(DWORD)(endtime - ticks.ft_i64),
22702271
QS_POSTMESSAGE|QS_TIMER|QS_SENDMESSAGE);
2272+
retry = 0;
22712273
if (resultp)
22722274
*resultp = result;
22732275
if (result == WAIT_TIMEOUT) {
@@ -2283,6 +2285,7 @@ win32_msgwait(pTHX_ DWORD count, LPHANDLE handles, DWORD timeout, LPDWORD result
22832285
if (result == WAIT_OBJECT_0 + count) {
22842286
/* Message has arrived - check it */
22852287
(void)win32_async_check(aTHX);
2288+
retry = 1;
22862289
}
22872290
else {
22882291
/* Not timeout or message - one of handles is ready */

0 commit comments

Comments
 (0)