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

Comparing cvsroot/AnyEvent-Fork/Fork.pm (file contents):
Revision 1.14 by root, Thu Apr 4 08:16:14 2013 UTC vs.
Revision 1.15 by root, Fri Apr 5 08:56:36 2013 UTC

1=head1 NAME 1=head1 NAME
2 2
3AnyEvent::Fork - everything you wanted to use fork() for, but couldn't 3AnyEvent::Fork - everything you wanted to use fork() for, but couldn't
4
5ATTENTION, this is a very early release, and very untested. Consider it a
6technology preview.
7 4
8=head1 SYNOPSIS 5=head1 SYNOPSIS
9 6
10 use AnyEvent::Fork; 7 use AnyEvent::Fork;
11 8
244use common::sense; 241use common::sense;
245 242
246use Socket (); 243use Socket ();
247 244
248use AnyEvent; 245use AnyEvent;
249use AnyEvent::Fork::Util;
250use AnyEvent::Util (); 246use AnyEvent::Util ();
251 247
252our $VERSION = $AnyEvent::Fork::Util::VERSION; 248use IO::FDPass;
249
250our $VERSION = 0.2;
253 251
254our $PERL; # the path to the perl interpreter, deduces with various forms of magic 252our $PERL; # the path to the perl interpreter, deduces with various forms of magic
255 253
256=item my $pool = new AnyEvent::Fork key => value... 254=item my $pool = new AnyEvent::Fork key => value...
257 255
282 # send the next "thing" in the queue - either a reference to an fh, 280 # send the next "thing" in the queue - either a reference to an fh,
283 # or a plain string. 281 # or a plain string.
284 282
285 if (ref $self->[2][0]) { 283 if (ref $self->[2][0]) {
286 # send fh 284 # send fh
287 AnyEvent::Fork::Util::fd_send fileno $self->[1], fileno ${ $self->[2][0] } 285 IO::FDPass::send fileno $self->[1], fileno ${ $self->[2][0] }
288 and shift @{ $self->[2] }; 286 and shift @{ $self->[2] };
289 287
290 } else { 288 } else {
291 # send string 289 # send string
292 my $len = syswrite $self->[1], $self->[2][0] 290 my $len = syswrite $self->[1], $self->[2][0]
332 require AnyEvent::Fork::Serve; 330 require AnyEvent::Fork::Serve;
333 $AnyEvent::Fork::Serve::OWNER = $parent; 331 $AnyEvent::Fork::Serve::OWNER = $parent;
334 close $fh; 332 close $fh;
335 $0 = "$_[1] of $parent"; 333 $0 = "$_[1] of $parent";
336 AnyEvent::Fork::Serve::serve ($slave); 334 AnyEvent::Fork::Serve::serve ($slave);
337 AnyEvent::Fork::Util::_exit 0; 335 exit 0;
338 } elsif (!$pid) { 336 } elsif (!$pid) {
339 die "AnyEvent::Fork::Early/Template: unable to fork template process: $!"; 337 die "AnyEvent::Fork::Early/Template: unable to fork template process: $!";
340 } 338 }
341 339
342 AnyEvent::Fork->_new ($fh) 340 AnyEvent::Fork->_new ($fh)
417 my $perl = $; 415 my $perl = $;
418 416
419 # first we try $^X, but the path must be absolute (always on win32), and end in sth. 417 # first we try $^X, but the path must be absolute (always on win32), and end in sth.
420 # that looks like perl. this obviously only works for posix and win32 418 # that looks like perl. this obviously only works for posix and win32
421 unless ( 419 unless (
422 (AnyEvent::Fork::Util::WIN32 || $perl =~ m%^/%) 420 ($^O eq "MSWin32" || $perl =~ m%^/%)
423 && $perl =~ m%[/\\]perl(?:[0-9]+(\.[0-9]+)+)?(\.exe)?$%i 421 && $perl =~ m%[/\\]perl(?:[0-9]+(\.[0-9]+)+)?(\.exe)?$%i
424 ) { 422 ) {
425 # if it doesn't look perlish enough, try Config 423 # if it doesn't look perlish enough, try Config
426 require Config; 424 require Config;
427 $perl = $Config::Config{perlpath}; 425 $perl = $Config::Config{perlpath};
438 Proc::FastSpawn::fd_inherit (fileno $fh, 0); 436 Proc::FastSpawn::fd_inherit (fileno $fh, 0);
439 437
440 # quick. also doesn't work in win32. of course. what did you expect 438 # quick. also doesn't work in win32. of course. what did you expect
441 #local $ENV{PERL5LIB} = join ":", grep !ref, @INC; 439 #local $ENV{PERL5LIB} = join ":", grep !ref, @INC;
442 my %env = %ENV; 440 my %env = %ENV;
443 $env{PERL5LIB} = join +(AnyEvent::Fork::Util::WIN32 ? ";" : ":"), grep !ref, @INC; 441 $env{PERL5LIB} = join +($^O eq "MSWin32" ? ";" : ":"), grep !ref, @INC;
444 442
445 Proc::FastSpawn::spawn ( 443 Proc::FastSpawn::spawn (
446 $perl, 444 $perl,
447 ["perl", "-MAnyEvent::Fork::Serve", "-e", "AnyEvent::Fork::Serve::me", fileno $slave, $$], 445 ["perl", "-MAnyEvent::Fork::Serve", "-e", "AnyEvent::Fork::Serve::me", fileno $slave, $$],
448 [map "$_=$env{$_}", keys %env], 446 [map "$_=$env{$_}", keys %env],
605 $self->_cmd (r => $func); 603 $self->_cmd (r => $func);
606} 604}
607 605
608=back 606=back
609 607
608=head1 TYPICAL PROBLEMS
609
610This section lists typical problems that remain. I hope by recognising
611them, most can be avoided.
612
613=over 4
614
615=item "leaked" file descriptors for exec'ed processes
616
617POSIX systems inherit file descriptors by default when exec'ing a new
618process. While perl itself laudably sets the close-on-exec flags on new
619file handles, most C libraries don't care, and even if all cared, it's
620often not possible to set the flag in a race-free manner.
621
622That means some file descriptors can leak through. And since it isn't
623possible to know which file descriptors are "good" and "neccessary" (or
624even to know which file descreiptors are open), there is no good way to
625close the ones that might harm.
626
627As an example of what "harm" can be done consider a web server that
628accepts connections and afterwards some module uses AnyEvent::Fork for the
629first time, causing it to fork and exec a new process, which might inherit
630the network socket. When the server closes the socket, it is still open
631in the child (which doesn't even know that) and the client might conclude
632that the connection is still fine.
633
634For the main program, there are multiple remedies available -
635L<AnyEvent::Fork::Early> is one, creating a process early and not using
636C<new_exec> is another, as in both cases, the first process can be exec'ed
637well before many random file descriptors are open.
638
639In general, the solution for these kind of problems is to fix the
640libraries or the code that leaks those file descriptors.
641
642Fortunately, most of these lekaed descriptors do no harm, other than
643sitting on some resources.
644
645=item "leaked" file descriptors for fork'ed processes
646
647Normally, L<AnyEvent::Fork> does start new processes by exec'ing them,
648which closes file descriptors not marked for being inherited.
649
650However, L<AnyEvent::Fork::Early> and L<AnyEvent::Fork::Template> offer
651a way to create these processes by forking, and this leaks more file
652descriptors than exec'ing them, as there is no way to mark descriptors as
653"close on fork".
654
655An example would be modules like L<EV>, L<IO::AIO> or L<Gtk2>. Both create
656pipes for internal uses, and L<Gtk2> might open a connection to the X
657server. L<EV> and L<IO::AIO> can deal with fork, but Gtk2 might have
658trouble with a fork.
659
660The solution is to either not load these modules before use'ing
661L<AnyEvent::Fork::Early> or L<AnyEvent::Fork::Template>, or to delay
662initialising them, for example, by calling C<init Gtk2> manually.
663
664=back
665
610=head1 PORTABILITY NOTES 666=head1 PORTABILITY NOTES
611 667
612Native win32 perls are somewhat supported (AnyEvent::Fork::Early is a nop, 668Native win32 perls are somewhat supported (AnyEvent::Fork::Early is a nop,
613and ::Template is not going to work), and it cost a lot of blood and sweat 669and ::Template is not going to work), and it cost a lot of blood and sweat
614to make it so, mostly due to the bloody broken perl that nobody seems to 670to make it so, mostly due to the bloody broken perl that nobody seems to

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines