AnyEvent-Fork

 view release on metacpan or  search on metacpan

Fork.pm  view on Meta::CPAN

      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 )