Skip Menu |

This queue is for tickets about the Parallel-Forker CPAN distribution.

Report information
The Basics
Id: 40886
Status: resolved
Priority: 0/
Queue: Parallel-Forker

People
Owner: Nobody in particular
Requestors: TONVOON [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: Multiple kill_tree_all from $SIG{TERM}
The line in the documentation which says: $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }; Is possibly a problem. This is because this signal will be inherited by the forked children and then $Fork->kill_tree_all will be called multiple times. We've seen some unpredictable segfaults from Storable.so which is used by Proc::ProcessTable to cache the tty information. My guess is that the file is removed by one of the kill_tree_all calls, and the child one expects the file to still be there and tries to access it or remove it.
There's a burried comment about this: "If your callback is going to fork, you'd be advised to have the child: $SIG{ALRM} = 'DEFAULT'; $SIG{CHLD} = 'DEFAULT'; This will prevent the child from inheriting the parent's handlers, and possibly confusing any child calls to waitpid." It's obviously better to be more defensive than that. Apply the below patch, and the SIG usage then changes to $SIG{TERM} = sub { $fork->kill_tree_all('TERM') if $fork && $fork->in_parent; die "Quitting...\n"; }; If this makes sense to you I'll push a new release with it plus related documentation & test fixes. Index: lib/Parallel/Forker.pm =================================================================== --- lib/Parallel/Forker.pm (revision 64594) +++ lib/Parallel/Forker.pm (working copy) @@ -38,8 +38,8 @@ _labels => {}, # List of process objects, keyed by label _runable => {}, # Process objects runable now, keyed by id _running => {}, # Process objects running now, keyed *PID* _in_child => 0, # In a child process, don't allow forking _run_after_eqn => undef,# Equation to eval to determine if ready to launch + _parent_pid => $$, # PID of initial process creating the forker max_proc => undef, # Number processes to launch, <1=any, +=that number use_sig_child => undef, # Default to not using SIGCHLD handler @_ @@ -50,6 +50,11 @@ #### ACCESSORS +sub in_parent { + my $self = shift; + return $self->{_parent_pid}==$$; +} + sub max_proc { my $self = shift; $self->{max_proc} = shift if $#_>=0; @@ -305,7 +310,7 @@ use Parallel::Forker; $Fork = new Parallel::Forker (use_sig_child=>1); $SIG{CHLD} = sub { Parallel::Forker::sig_child($Fork); }; - $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }; + $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork && $Fork->in_parent; die "Quitting...\n"; }; $Fork->schedule (run_on_start => sub {print "child work here...";},
Hi! On Thu Nov 13 09:55:39 2008, WSNYDER wrote: Show quoted text
> There's a burried comment about this: > > "If your callback is going to fork, you'd be advised to have the child: > > $SIG{ALRM} = 'DEFAULT'; > $SIG{CHLD} = 'DEFAULT'; > > This will prevent the child from inheriting the parent's handlers, and > possibly confusing any child calls to waitpid." > > It's obviously better to be more defensive than that. > > Apply the below patch, and the SIG usage then changes to > > $SIG{TERM} = sub { $fork->kill_tree_all('TERM') if $fork && > $fork->in_parent; die "Quitting...\n"; }; > > If this makes sense to you I'll push a new release with it plus related > documentation & test fixes.
Yes, this makes sense. Much appreciated. Ton
FYI 1.223 has been released with these changes. It will be on CPAN in a hour to day.