Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
$self->{to_close}{$childread->fileno} = $childread;
$self->{to_close}{$childwrite->fileno} = $childwrite;
}
elsif( $via == FD_VIA_SOCKETPAIR ) {
my ( $myfd, $childfd ) = IO::Async::OS->socketpair( $opts->{family}, $opts->{socktype} ) or croak "Unable to socketpair() - $!";
$handle->configure( handle => $myfd );
if( $key eq "stdio" ) {
push @setup, stdin => [ dup => $childfd ], stdout => [ dup => $childfd ];
}
else {
push @setup, $key => [ dup => $childfd ];
}
$self->{to_close}{$childfd->fileno} = $childfd;
}
else {
croak "Unsure what to do with fd_via==$via";
}
$self->add_child( $handle );
unless( $write_only ) {
push @$finish_futures, $handle->new_close_future;
}
}
return @setup;
}
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
$self->{code} or $self->{command} or
croak "Require either 'code' or 'command' in $self";
$self->can_event( "on_finish" ) or
croak "Expected either an on_finish callback or to be able to ->on_finish";
my @setup;
push @setup, @{ $self->{setup} } if $self->{setup};
push @setup, $self->_prepare_fds( $loop );
my $finish_futures = delete $self->{finish_futures};
my ( $exitcode, $dollarbang, $dollarat );
push @$finish_futures, my $exit_future = $loop->new_future;
$self->{pid} = $loop->spawn_child(
code => $self->{code},
command => $self->{command},
setup => \@setup,
on_exit => $self->_capture_weakself( sub {
( my $self, undef, $exitcode, $dollarbang, $dollarat ) = @_;
$self->debug_printf( "EXIT status=0x%04x", $exitcode ) if $self;
$exit_future->done unless $exit_future->is_cancelled;
} ),
);
$self->{running} = 1;
$self->SUPER::_add_to_loop( @_ );
$_->close for values %{ delete $self->{to_close} };
my $is_code = defined $self->{code};
$self->{finish_future} = Future->needs_all( @$finish_futures )
->on_done( $self->_capture_weakself( sub {
my $self = shift or return;
$self->{exitcode} = $exitcode;
$self->{dollarbang} = $dollarbang;
$self->{dollarat} = $dollarat;
undef $self->{running};
if( $is_code ? $dollarat eq "" : $dollarbang == 0 ) {
$self->invoke_event( on_finish => $exitcode );
}
else {
$self->maybe_invoke_event( on_exception => $dollarat, $dollarbang, $exitcode ) or
# Don't have a way to report dollarbang/dollarat
$self->invoke_event( on_finish => $exitcode );
}
$self->remove_from_parent;
} ),
);
}
sub DESTROY
{
my $self = shift;
$self->{finish_future}->cancel if $self->{finish_future};
}
sub notifier_name
{
my $self = shift;
if( length( my $name = $self->SUPER::notifier_name ) ) {
return $name;
}
return "nopid" unless my $pid = $self->pid;
return "[$pid]" unless $self->is_running;
return "$pid";
}
=head1 METHODS
=cut
=head2 pid
$pid = $process->pid
( run in 0.620 second using v1.01-cache-2.11-cpan-6de40a662fe )