AnyEvent-Fork
view release on metacpan or search on metacpan
die "AnyEvent::Fork::Early/Template: unable to fork template process: $!";
}
AnyEvent::Fork->_new ($fh, $pid)
}
=item my $proc = new AnyEvent::Fork
Create a new "empty" perl interpreter process and returns its process
object for further manipulation.
The new process is forked from a template process that is kept around
for this purpose. When it doesn't exist yet, it is created by a call to
C<new_exec> first and then stays around for future calls.
=cut
sub new {
my $class = shift;
$TEMPLATE ||= $class->new_exec;
$TEMPLATE->fork
}
=item $new_proc = $proc->fork
Forks C<$proc>, creating a new process, and returns the process object
of the new process.
If any of the C<send_> functions have been called before fork, then they
will be cloned in the child. For example, in a pre-forked server, you
might C<send_fh> the listening socket into the template process, and then
keep calling C<fork> and C<run>.
=cut
sub fork {
my ($self) = @_;
my ($fh, $slave) = AnyEvent::Util::portable_socketpair;
$self->send_fh ($slave);
$self->_cmd ("f");
AnyEvent::Fork->_new ($fh)
}
=item my $proc = new_exec AnyEvent::Fork
Create a new "empty" perl interpreter process and returns its process
object for further manipulation.
Unlike the C<new> method, this method I<always> spawns a new perl process
(except in some cases, see L<AnyEvent::Fork::Early> for details). This
reduces the amount of memory sharing that is possible, and is also slower.
You should use C<new> whenever possible, except when having a template
process around is unacceptable.
The path to the perl interpreter is divined using various methods - first
C<$^X> is investigated to see if the path ends with something that looks
as if it were the perl interpreter. Failing this, the module falls back to
using C<$Config::Config{perlpath}>.
The path to perl can also be overridden by setting the global variable
C<$AnyEvent::Fork::PERL> - it's value will be used for all subsequent
invocations.
=cut
our $PERL;
sub new_exec {
my ($self) = @_;
return $EARLY->fork
if $EARLY;
unless (defined $PERL) {
# first find path of perl
my $perl = $^X;
# first we try $^X, but the path must be absolute (always on win32), and end in sth.
# that looks like perl. this obviously only works for posix and win32
unless (
($^O eq "MSWin32" || $perl =~ m%^/%)
&& $perl =~ m%[/\\]perl(?:[0-9]+(\.[0-9]+)+)?(\.exe)?$%i
) {
# if it doesn't look perlish enough, try Config
require Config;
$perl = $Config::Config{perlpath};
$perl =~ s/(?:\Q$Config::Config{_exe}\E)?$/$Config::Config{_exe}/;
}
$PERL = $perl;
}
require Proc::FastSpawn;
my ($fh, $slave) = AnyEvent::Util::portable_socketpair;
Proc::FastSpawn::fd_inherit (fileno $slave);
# new fh's should always be set cloexec (due to $^F),
# but hey, not on win32, so we always clear the inherit flag.
Proc::FastSpawn::fd_inherit (fileno $fh, 0);
# quick. also doesn't work in win32. of course. what did you expect
#local $ENV{PERL5LIB} = join ":", grep !ref, @INC;
my %env = %ENV;
$env{PERL5LIB} = join +($^O eq "MSWin32" ? ";" : ":"), grep !ref, @INC;
my $pid = Proc::FastSpawn::spawn (
$PERL,
[$PERL, "-MAnyEvent::Fork::Serve", "-e", "AnyEvent::Fork::Serve::me", fileno $slave, $$],
[map "$_=$env{$_}", keys %env],
) or die "unable to spawn AnyEvent::Fork server: $!";
$self->_new ($fh, $pid)
}
=item $pid = $proc->pid
Returns the process id of the process I<iff it is a direct child of the
process running AnyEvent::Fork>, and C<undef> otherwise. As a general
rule (that you cannot rely upon), processes created via C<new_exec>,
L<AnyEvent::Fork::Early> or L<AnyEvent::Fork::Template> are direct
children, while all other processes are not.
Or in other words, you do not normally have to take care of zombies for
processes created via C<new>, but when in doubt, or zombies are a problem,
you need to check whether a process is a diretc child by calling this
method, and possibly creating a child watcher or reap it manually.
=cut
sub pid {
$_[0][PID]
}
=item $proc = $proc->eval ($perlcode, @args)
Evaluates the given C<$perlcode> as ... Perl code, while setting C<@_>
to the strings specified by C<@args>, in the "main" package (so you can
access the args using C<$_[0]> and so on, but not using implicit C<shit>
( run in 1.566 second using v1.01-cache-2.11-cpan-99c4e6809bf )