On Fri Feb 22 08:02:38 2019, PEVANS wrote:
Show quoted text> ->post_fork ought to create a new signal pipe, as if the parent and
> child share one Bad Things will happen
Fixed. Hopefully.
--
Paul Evans
=== modified file 'lib/IO/Async/Loop.pm'
--- old/lib/IO/Async/Loop.pm 2019-11-23 17:39:12 +0000
+++ new/lib/IO/Async/Loop.pm 2019-11-23 18:27:10 +0000
@@ -594,7 +594,9 @@
sub post_fork
{
- # empty
+ my $self = shift;
+
+ IO::Async::OS->post_fork( $self );
}
###########
=== modified file 'lib/IO/Async/LoopTests.pm'
--- old/lib/IO/Async/LoopTests.pm 2019-06-27 17:51:07 +0000
+++ new/lib/IO/Async/LoopTests.pm 2019-11-23 18:27:10 +0000
@@ -580,7 +580,7 @@
=cut
-use constant count_tests_signal => 14;
+use constant count_tests_signal => 15;
sub run_tests_signal
{
unless( IO::Async::OS->HAVE_SIGNALS ) {
@@ -650,6 +650,17 @@
ok( exception { $loop->attach_signal( 'this signal name does not exist', sub {} ) },
'Bad signal name fails' );
+
+ undef $caught;
+ $loop->attach_signal( TERM => sub { $caught++ } );
+
+ $loop->post_fork;
+
+ kill SIGTERM, $$;
+
+ $loop->loop_once( 0.1 );
+
+ is( $caught, 1, '$caught SIGTERM after ->post_fork' );
}
=head2 idle
=== modified file 'lib/IO/Async/OS.pm'
--- old/lib/IO/Async/OS.pm 2019-06-27 17:51:07 +0000
+++ new/lib/IO/Async/OS.pm 2019-11-23 18:27:10 +0000
@@ -548,6 +548,34 @@
=cut
+sub _setup_sigpipe
+{
+ my $self = shift;
+ my ( $loop ) = @_;
+
+ require IO::Async::Handle;
+
+ my ( $reader, $sigpipe ) = $self->pipepair or croak "Cannot pipe() - $!";
+ $_->blocking( 0 ) for $reader, $sigpipe;
+
+ $loop->{os}{sigpipe} = $sigpipe;
+
+ my $sigwatch = $loop->{os}{sigwatch};
+
+ $loop->add( $loop->{os}{sigpipe_reader} = IO::Async::Handle->new(
+ notifier_name => "sigpipe",
+ read_handle => $reader,
+ on_read_ready => sub {
+ sysread $reader, my $buffer, 8192 or return;
+ foreach my $signum ( unpack "I*", $buffer ) {
+ $sigwatch->{$signum}->() if $sigwatch->{$signum};
+ }
+ },
+ ) );
+
+ return $sigpipe;
+}
+
sub loop_watch_signal
{
my $self = shift;
@@ -559,26 +587,7 @@
my $signum = $self->signame2num( $signal );
my $sigwatch = $loop->{os}{sigwatch} ||= {}; # {$num} = $code
- my $sigpipe;
- unless( $sigpipe = $loop->{os}{sigpipe} ) {
- require IO::Async::Handle;
-
- ( my $reader, $sigpipe ) = $self->pipepair or croak "Cannot pipe() - $!";
- $_->blocking( 0 ) for $reader, $sigpipe;
-
- $loop->{os}{sigpipe} = $sigpipe;
-
- $loop->add( $loop->{os}{sigpipe_reader} = IO::Async::Handle->new(
- notifier_name => "sigpipe",
- read_handle => $reader,
- on_read_ready => sub {
- sysread $reader, my $buffer, 8192 or return;
- foreach my $signum ( unpack "I*", $buffer ) {
- $sigwatch->{$signum}->() if $sigwatch->{$signum};
- }
- },
- ) );
- }
+ my $sigpipe = $loop->{os}{sigpipe} // $self->_setup_sigpipe( $loop );
my $signum_str = pack "I", $signum;
$SIG{$signal} = sub { syswrite $sigpipe, $signum_str };
@@ -613,6 +622,26 @@
return 0 .. OPEN_MAX_FD;
}
+sub post_fork
+{
+ my $self = shift;
+ my ( $loop ) = @_;
+
+ if( $loop->{os}{sigpipe} ) {
+ $loop->remove( $loop->{os}{sigpipe_reader} );
+ undef $loop->{os}{sigpipe};
+
+ my $sigwatch = $loop->{os}{sigwatch};
+
+ foreach my $signal ( keys %SIG ) {
+ my $signum = $self->signame2num( $signal ) or next;
+ my $code = $sigwatch->{$signum} or next;
+
+ $self->loop_watch_signal( $loop, $signal, $code );
+ }
+ }
+}
+
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>