Skip to content

Instantly share code, notes, and snippets.

/SubProcess.pm Secret

Created August 26, 2016 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4d5c89e4132a492f98399bc0febd90cf to your computer and use it in GitHub Desktop.
Save anonymous/4d5c89e4132a492f98399bc0febd90cf to your computer and use it in GitHub Desktop.
package Mojo::IOLoop::SubProcess;
use Mojo::Base -base;
use Config;
use Mojo::IOLoop;
use Mojo::IOLoop::Stream;
use Storable;
has ioloop => sub { Mojo::IOLoop->singleton };
has serializer => sub { \&Storable::freeze };
has deserializer => sub { \&Storable::thaw };
sub run {
my ($self, $first, $second) = @_;
# No fork emulation support
say 'Subprocess does not support fork emulation.' and exit 0
if $Config{d_pseudofork};
# Pipe for subprocess communication
pipe(my $reader, my $writer) or die "Can't create pipe: $!";
# Parent
die "Can't fork: $!" unless defined(my $pid = fork);
if ($pid) {
my $stream = Mojo::IOLoop::Stream->new($reader);
$self->ioloop->stream($stream);
my $buffer;
$stream->on(read => sub { $buffer .= pop });
$stream->on(
close => sub {
waitpid $pid, 0;
return $second->($self, "Non-zero exit status (@{[$? >> 8]})") if $?;
my $result = eval { $self->deserializer->($buffer) } || [];
$second->($self, $@, @$result);
}
);
}
# Child
else {
$self->ioloop->reset;
print $writer $self->serializer->([$first->()]);
exit 0;
}
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment