In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/3aa0ac5aa5f5cff1b95ae5ff8641818c450e4b16?hp=c9989a7404d7d04d5a3de35f7783e3fe298e69be>
- Log ----------------------------------------------------------------- commit 3aa0ac5aa5f5cff1b95ae5ff8641818c450e4b16 Author: Jan Dubois <[email protected]> Date: Tue Mar 15 12:34:10 2011 -0700 Don't wait for SIGTERM'ed forked children on Windows SIGTERM may never get delivered when a thread/process is blocked in a system call. To avoid a deadlock Perl will now no longer wait for children to terminate after they have been signalled with SIGTERM. Note: this *only* applies to fork() emulation on Windows. Read pod/perlfork.pod for context on other limitation of this emulation. ----------------------------------------------------------------------- Summary of changes: pod/perldelta.pod | 18 ++++++++++++++++++ pod/perlfork.pod | 31 ++++++++++++++++++++++--------- win32/win32.c | 8 ++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 8019dd3..b6ae3f7 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -73,6 +73,24 @@ none, proceeds to stringify the reference and append the file and line number. This allows simple uses of C<warn> for debugging to continue to work as they did before. +=head2 fork() emulation will not wait for signalled children + +On Windows parent processes would not terminate until all forked +childred had terminated first. However, C<kill('KILL', ...)> is +inherently unstable on pseudo-processes, and C<kill('TERM', ...)> +might not get delivered if the child if blocked in a system call. + +To avoid the deadlock and still provide a safe mechanism to terminate +the hosting process, Perl will now no longer wait for children that +have been sent a SIGTERM signal. It is up to the parent process to +waitpid() for these children if child clean-up processing must be +allowed to finish. However, it is also the responsibility of the +parent then to avoid the deadlock by making sure the child process +can't be blocked on I/O either. + +See L<perlfork> for more information about the fork() emulation on +Windows. + =head1 Deprecations XXX Any deprecated features, syntax, modules etc. should be listed here. diff --git a/pod/perlfork.pod b/pod/perlfork.pod index e7bcff4..709d053 100644 --- a/pod/perlfork.pod +++ b/pod/perlfork.pod @@ -77,12 +77,24 @@ and return its status. =item kill() -kill() can be used to terminate a pseudo-process by passing it the ID returned -by fork(). This should not be used except under dire circumstances, because -the operating system may not guarantee integrity of the process resources -when a running thread is terminated. Note that using kill() on a -pseudo-process() may typically cause memory leaks, because the thread that -implements the pseudo-process does not get a chance to clean up its resources. +C<kill('KILL', ...)> can be used to terminate a pseudo-process by +passing it the ID returned by fork(). This should not be used except +under dire circumstances, because the operating system may not +guarantee integrity of the process resources when a running thread is +terminated. Note that using C<kill('KILL', ...)> on a +pseudo-process() may typically cause memory leaks, because the thread +that implements the pseudo-process does not get a chance to clean up +its resources. + +C<kill('TERM', ...)> can also be used on pseudo-processes, but the +signal will not be delivered while the pseudo-process is blocked by a +system call, e.g. waiting for a socket to connect, or trying to read +from a socket with no data available. Starting in Perl 5.14 the +parent process will not wait for children to exit once they have been +signalled with C<kill('TERM', ...)> to avoid deadlock during process +exit. You will have to explicitly call waitpid() to make sure the +child has time to clean-up itself, but you are then also responsible +that the child is not blocking on I/O either. =item exec() @@ -137,9 +149,10 @@ to complete before they exit. This means that the parent and every pseudo-child created by it that is also a pseudo-parent will only exit after their pseudo-children have exited. -A way to mark a pseudo-processes as running detached from their parent (so -that the parent would not have to wait() for them if it doesn't want to) -will be provided in future. +Starting with Perl 5.14 a parent will not wait() automatically +for any child that has been signalled with C<sig('TERM', ...)> +to avoid a deadlock in case the child is blocking on I/O and +never receives the signal. =head1 CAVEATS AND LIMITATIONS diff --git a/win32/win32.c b/win32/win32.c index 2394524..b8bb5bb 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1310,6 +1310,14 @@ win32_kill(int pid, int sig) if ((hwnd != NULL && PostMessage(hwnd, WM_USER_KILL, sig, 0)) || PostThreadMessage(-pid, WM_USER_KILL, sig, 0)) { + /* Don't wait for child process to terminate after we send a SIGTERM + * because the child may be blocked in a system call and never receive + * the signal. + */ + if (sig == SIGTERM) { + Sleep(0); + remove_dead_pseudo_process(child); + } /* It might be us ... */ PERL_ASYNC_CHECK(); return 0; -- Perl5 Master Repository
