ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Fork/Fork.pm
(Generate patch)

Comparing AnyEvent-Fork/Fork.pm (file contents):
Revision 1.53 by root, Fri Apr 26 15:44:44 2013 UTC vs.
Revision 1.56 by root, Sun Apr 28 13:47:52 2013 UTC

450use AnyEvent; 450use AnyEvent;
451use AnyEvent::Util (); 451use AnyEvent::Util ();
452 452
453use IO::FDPass; 453use IO::FDPass;
454 454
455our $VERSION = '1.0'; 455our $VERSION = 1.1;
456 456
457# the early fork template process 457# the early fork template process
458our $EARLY; 458our $EARLY;
459 459
460# the empty template process 460# the empty template process
609The path to the perl interpreter is divined using various methods - first 609The path to the perl interpreter is divined using various methods - first
610C<$^X> is investigated to see if the path ends with something that sounds 610C<$^X> is investigated to see if the path ends with something that sounds
611as if it were the perl interpreter. Failing this, the module falls back to 611as if it were the perl interpreter. Failing this, the module falls back to
612using C<$Config::Config{perlpath}>. 612using C<$Config::Config{perlpath}>.
613 613
614The path to perl can also be overriden by setting the global variable
615C<$AnyEvent::Fork::PERL> - it's value will be used for all subsequent
616invocations.
617
614=cut 618=cut
619
620our $PERL;
615 621
616sub new_exec { 622sub new_exec {
617 my ($self) = @_; 623 my ($self) = @_;
618 624
619 return $EARLY->fork 625 return $EARLY->fork
620 if $EARLY; 626 if $EARLY;
621 627
628 unless (defined $PERL) {
622 # first find path of perl 629 # first find path of perl
623 my $perl = $; 630 my $perl = $;
624 631
625 # first we try $^X, but the path must be absolute (always on win32), and end in sth. 632 # first we try $^X, but the path must be absolute (always on win32), and end in sth.
626 # that looks like perl. this obviously only works for posix and win32 633 # that looks like perl. this obviously only works for posix and win32
627 unless ( 634 unless (
628 ($^O eq "MSWin32" || $perl =~ m%^/%) 635 ($^O eq "MSWin32" || $perl =~ m%^/%)
629 && $perl =~ m%[/\\]perl(?:[0-9]+(\.[0-9]+)+)?(\.exe)?$%i 636 && $perl =~ m%[/\\]perl(?:[0-9]+(\.[0-9]+)+)?(\.exe)?$%i
630 ) { 637 ) {
631 # if it doesn't look perlish enough, try Config 638 # if it doesn't look perlish enough, try Config
632 require Config; 639 require Config;
633 $perl = $Config::Config{perlpath}; 640 $perl = $Config::Config{perlpath};
634 $perl =~ s/(?:\Q$Config::Config{_exe}\E)?$/$Config::Config{_exe}/; 641 $perl =~ s/(?:\Q$Config::Config{_exe}\E)?$/$Config::Config{_exe}/;
642 }
643
644 $PERL = $perl;
635 } 645 }
636 646
637 require Proc::FastSpawn; 647 require Proc::FastSpawn;
638 648
639 my ($fh, $slave) = AnyEvent::Util::portable_socketpair; 649 my ($fh, $slave) = AnyEvent::Util::portable_socketpair;
647 #local $ENV{PERL5LIB} = join ":", grep !ref, @INC; 657 #local $ENV{PERL5LIB} = join ":", grep !ref, @INC;
648 my %env = %ENV; 658 my %env = %ENV;
649 $env{PERL5LIB} = join +($^O eq "MSWin32" ? ";" : ":"), grep !ref, @INC; 659 $env{PERL5LIB} = join +($^O eq "MSWin32" ? ";" : ":"), grep !ref, @INC;
650 660
651 my $pid = Proc::FastSpawn::spawn ( 661 my $pid = Proc::FastSpawn::spawn (
652 $perl, 662 $PERL,
653 ["perl", "-MAnyEvent::Fork::Serve", "-e", "AnyEvent::Fork::Serve::me", fileno $slave, $$], 663 ["perl", "-MAnyEvent::Fork::Serve", "-e", "AnyEvent::Fork::Serve::me", fileno $slave, $$],
654 [map "$_=$env{$_}", keys %env], 664 [map "$_=$env{$_}", keys %env],
655 ) or die "unable to spawn AnyEvent::Fork server: $!"; 665 ) or die "unable to spawn AnyEvent::Fork server: $!";
656 666
657 $self->_new ($fh, $pid) 667 $self->_new ($fh, $pid)
849 $self->_cmd (r => $func); 859 $self->_cmd (r => $func);
850} 860}
851 861
852=back 862=back
853 863
854=head2 ADVANCED METHODS
855
856=over 4
857
858=item new_from_stdio AnyEvent::Fork $fh
859
860Assume that you have a perl interpreter running (without any special
861options or a program) somewhere and it has it's STDIN and STDOUT connected
862to the C<$fh> somehow. I.e. exactly the state perl is in when you start it
863without any arguments:
864
865 perl
866
867Then you can create an C<AnyEvent::Fork> object out of this perl
868interpreter with this constructor.
869
870When the usefulness of this isn't immediately clear, imagine you manage to
871run a perl interpreter remotely (F<ssh remotemachine perl>), then you can
872manage it mostly like a local C<AnyEvent::Fork> child.
873
874This works without any module support, i.e. the remote F<perl> does not
875need to have any special modules installed.
876
877There are a number of limitations though: C<send_fh> will only work if the
878L<IO::FDPass> module is loadable by the remote perl and the two processes
879are connected in a way that let's L<IO::FDPass> do it's work.
880
881This will therefore not work over a network conenction. From this follows
882that C<fork> will also not work under these circumstances, as it relies on
883C<send_fh> internally.
884
885=cut
886
887sub new_from_stdio {
888 my ($class, $fh) = @_;
889
890 my $self = $class->_new ($fh);
891
892 # send startup code
893 push @{ $self->[QUEUE] },
894 (do "AnyEvent/Fork/serve.pl")
895 . <<'EOF';
896{
897 open my $fh, "+<&0"
898 or die "AnyEvent::Fork::Serve::stdio: unable to open communications socket: $!\n";
899 open STDIN , ">&2";
900 open STDOUT, ">&2";
901
902 $OWNER = "another process";
903 $0 = "AnyEvent::Fork/stdio of $OWNER";
904
905 @_ = $fh;
906}
907
908&serve;
909__END__
910EOF
911
912 # the data is only sent when the user requests additional things, which
913 # is likely early enough for our purposes.
914
915 $self
916}
917
918=back
919
920=head2 EXPERIMENTAL METHODS 864=head2 EXPERIMENTAL METHODS
921 865
922These methods might go away completely or change behaviour, a any time. 866These methods might go away completely or change behaviour, at any time.
923 867
924=over 4 868=over 4
925 869
926=item $proc->to_fh ($cb->($fh)) # EXPERIMENTAL, MIGHT BE REMOVED 870=item $proc->to_fh ($cb->($fh)) # EXPERIMENTAL, MIGHT BE REMOVED
927 871

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines