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

Reply via email to