Skip to content

Commit

Permalink
Avoid race codition when setting process exit code on Windows.
Browse files Browse the repository at this point in the history
A Perl program using fork() emulation on Windows may end up
kill()ing the forked child and exiting immediately.  There
is a race condition where the process exit code may be
changed to '9' (the signal used to kill the child thread),
overriding the value the parent thread used in ExitProcess()
(called implicitly with the return value of main()).

Giving up the remainder of the time-slice after terminating
a child thread seems to eliminate this race.

This bug is responsible for various CPAN test failures,
where all tests seem to pass, but Test::Harness still
reports: "Dubious, test returned 9 (wstat 2304, 0x900)"
(e.g. HTTP-Server-Simple, tests based on Test-TCP).

See also https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
  • Loading branch information
jandubois committed Mar 11, 2011
1 parent 11883c8 commit 82e2458
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
12 changes: 12 additions & 0 deletions t/op/fork.t
Original file line number Diff line number Diff line change
Expand Up @@ -452,3 +452,15 @@ EXPECT
OPTION random
child: called as [main::f(foo,bar)]
waitpid() returned ok
########
# Windows 2000: https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
system $^X, "-e", "if (\$pid=fork){sleep 1;kill(9, \$pid)} else {sleep 5}";
print $?>>8, "\n";
EXPECT
0
########
# Windows 7: https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
system $^X, "-e", "if (\$pid=fork){kill(9, \$pid)} else {sleep 5}";
print $?>>8, "\n";
EXPECT
0
7 changes: 7 additions & 0 deletions win32/win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,13 @@ win32_kill(int pid, int sig)
case 9:
/* kill -9 style un-graceful exit */
if (TerminateThread(hProcess, sig)) {
/* Allow the scheduler to finish cleaning up the other thread.
* Otherwise, if we ExitProcess() before another context switch
* happens we will end up with a process exit code of "sig" instead
* of our own exit status.
* See also: https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
*/
Sleep(0);
remove_dead_pseudo_process(child);
return 0;
}
Expand Down

0 comments on commit 82e2458

Please sign in to comment.