Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
return 1;
}
# Internal constructor
sub new
{
my $class = shift;
my ( %params ) = @_;
my $loop = delete $params{loop} or croak "Expected a 'loop'";
my $self = bless {
loop => $loop,
}, $class;
weaken( $self->{loop} );
return $self;
}
=head1 METHODS
When active, the following methods are available on the containing C<Loop>
object.
=cut
=head2 spawn_child
$pid = $loop->spawn_child( %params )
This method creates a new child process to run a given code block or command.
The C<%params> hash takes the following keys:
=over 8
=item command => ARRAY or STRING
Either a reference to an array containing the command and its arguments, or a
plain string containing the command. This value is passed into perl's
C<exec> function.
=item code => CODE
A block of code to execute in the child process. It will be called in scalar
context inside an C<eval> block.
=item setup => ARRAY
A reference to an array which gives file descriptors to set up in the child
process before running the code or command. See below.
=item on_exit => CODE
A continuation to be called when the child processes exits. It will be invoked
in the following way:
$on_exit->( $pid, $exitcode, $dollarbang, $dollarat )
The second argument is passed the plain perl C<$?> value.
=back
Exactly one of the C<command> or C<code> keys must be specified.
If the C<command> key is used, the given array or string is executed using the
C<exec> function.
If the C<code> key is used, the return value will be used as the C<exit(2)>
code from the child if it returns (or 255 if it returned C<undef> or thows an
exception).
Case | ($exitcode >> 8) | $dollarbang | $dollarat
--------------+------------------------+-------------+----------
exec succeeds | exit code from program | 0 | ""
exec fails | 255 | $! | ""
$code returns | return value | $! | ""
$code dies | 255 | $! | $@
It is usually more convenient to use the C<open_child> method in simple cases
where an external program is being started in order to interact with it via
file IO, or even C<run_child> when only the final result is required, rather
than interaction while it is running.
=cut
sub spawn_child
{
my $self = shift;
my %params = @_;
my $command = delete $params{command};
my $code = delete $params{code};
my $setup = delete $params{setup};
my $on_exit = delete $params{on_exit};
if( %params ) {
croak "Unrecognised options to spawn: " . join( ",", keys %params );
}
defined $command and defined $code and
croak "Cannot pass both 'command' and 'code' to spawn";
defined $command or defined $code or
croak "Must pass one of 'command' or 'code' to spawn";
my @setup = defined $setup ? $self->_check_setup_and_canonicise( $setup ) : ();
my $loop = $self->{loop};
my ( $readpipe, $writepipe );
{
# Ensure it's FD_CLOEXEC - this is a bit more portable than manually
# fiddling with F_GETFL and F_SETFL (e.g. MSWin32)
local $^F = -1;
( $readpipe, $writepipe ) = IO::Async::OS->pipepair or croak "Cannot pipe() - $!";
}
( run in 0.523 second using v1.01-cache-2.11-cpan-39bf76dae61 )