--- AnyEvent/lib/AnyEvent.pm 2008/09/06 07:00:45 1.180 +++ AnyEvent/lib/AnyEvent.pm 2009/03/26 07:47:42 1.196 @@ -139,6 +139,12 @@ callback when the event occurs (of course, only when the event model is in control). +Note that B +potentially in use by the event loop (such as C<$_> or C<$[>) and that B<< +callbacks must not C >>. The former is good programming practise in +Perl and the latter stems from the fact that exception handling differs +widely between event loops. + To disable the watcher you have to destroy it (e.g. by setting the variable you store it in to C or otherwise deleting all references to it). @@ -342,11 +348,18 @@ You can also watch on a child process exit and catch its exit status. The child process is specified by the C argument (if set to C<0>, it -watches for any child process exit). The watcher will trigger as often -as status change for the child are received. This works by installing a -signal handler for C. The callback will be called with the pid -and exit status (as returned by waitpid), so unlike other watcher types, -you I rely on child watcher callback arguments. +watches for any child process exit). The watcher will triggered only when +the child process has finished and an exit status is available, not on +any trace events (stopped/continued). + +The callback will be called with the pid and exit status (as returned by +waitpid), so unlike other watcher types, you I rely on child watcher +callback arguments. + +This watcher type works by installing a signal handler for C, +and since it cannot be shared, nothing else should use SIGCHLD or reap +random child processes (waiting for specific child processes, e.g. inside +C, is just fine). There is a slight catch to child watchers, however: you usually start them I the child process was created, and this means the process could @@ -820,9 +833,9 @@ A non-blocking interface to the Internet Go Server protocol (used by L). -=item L +=item L -AnyEvent based IRC client module family. +AnyEvent based IRC client module family (replacing the older Net::IRC3). =item L @@ -856,7 +869,7 @@ use Carp; -our $VERSION = 4.233; +our $VERSION = 4.341; our $MODEL; our $AUTOLOAD; @@ -999,8 +1012,6 @@ sub _dupfh($$$$) { my ($poll, $fh, $r, $w) = @_; - require Fcntl; - # cygwin requires the fh mode to be matching, unix doesn't my ($rw, $mode) = $poll eq "r" ? ($r, "<") : $poll eq "w" ? ($w, ">") @@ -1023,7 +1034,7 @@ *_time = \&Time::HiRes::time; # if (eval "use POSIX (); (POSIX::times())... } else { - *_time = \&CORE::time; # epic fail + *_time = sub { time }; # epic fail } } @@ -1038,17 +1049,46 @@ # default implementation for ->signal -our %SIG_CB; +our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); + +sub _signal_exec { + while (%SIG_EV) { + sysread $SIGPIPE_R, my $dummy, 4; + for (keys %SIG_EV) { + delete $SIG_EV{$_}; + $_->() for values %{ $SIG_CB{$_} || {} }; + } + } +} sub signal { my (undef, %arg) = @_; + unless ($SIGPIPE_R) { + if (AnyEvent::WIN32) { + ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe (); + AnyEvent::Util::fh_nonblocking ($SIGPIPE_R) if $SIGPIPE_R; + AnyEvent::Util::fh_nonblocking ($SIGPIPE_W) if $SIGPIPE_W; # just in case + } else { + pipe $SIGPIPE_R, $SIGPIPE_W; + require Fcntl; + fcntl $SIGPIPE_R, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_R; + fcntl $SIGPIPE_W, &Fcntl::F_SETFL, &Fcntl::O_NONBLOCK if $SIGPIPE_W; # just in case + } + + $SIGPIPE_R + or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n"; + + $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R, poll => "r", cb => \&_signal_exec); + } + my $signal = uc $arg{signal} or Carp::croak "required option 'signal' is missing"; $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; $SIG{$signal} ||= sub { - $_->() for values %{ $SIG_CB{$signal} || {} }; + syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; + undef $SIG_EV{$signal}; }; bless [$signal, $arg{cb}], "AnyEvent::Base::Signal" @@ -1258,7 +1298,7 @@ This variable can effectively be used for denial-of-service attacks against local programs (e.g. when setuid), although the impact is likely -small, as the program has to handle connection errors already- +small, as the program has to handle conenction and other failures anyways. Examples: C - prefer IPv4 over IPv6, but support both and try to use both. C @@ -1528,16 +1568,16 @@ =head3 Results name watchers bytes create invoke destroy comment - EV/EV 400000 244 0.56 0.46 0.31 EV native interface - EV/Any 100000 244 2.50 0.46 0.29 EV + AnyEvent watchers - CoroEV/Any 100000 244 2.49 0.44 0.29 coroutines + Coro::Signal - Perl/Any 100000 513 4.92 0.87 1.12 pure perl implementation - Event/Event 16000 516 31.88 31.30 0.85 Event native interface - Event/Any 16000 590 35.75 31.42 1.08 Event + AnyEvent watchers - Glib/Any 16000 1357 98.22 12.41 54.00 quadratic behaviour - Tk/Any 2000 1860 26.97 67.98 14.00 SEGV with >> 2000 watchers - POE/Event 2000 6644 108.64 736.02 14.73 via POE::Loop::Event - POE/Select 2000 6343 94.13 809.12 565.96 via POE::Loop::Select + EV/EV 400000 224 0.47 0.35 0.27 EV native interface + EV/Any 100000 224 2.88 0.34 0.27 EV + AnyEvent watchers + CoroEV/Any 100000 224 2.85 0.35 0.28 coroutines + Coro::Signal + Perl/Any 100000 452 4.13 0.73 0.95 pure perl implementation + Event/Event 16000 517 32.20 31.80 0.81 Event native interface + Event/Any 16000 590 35.85 31.55 1.06 Event + AnyEvent watchers + Glib/Any 16000 1357 102.33 12.31 51.00 quadratic behaviour + Tk/Any 2000 1860 27.20 66.31 14.00 SEGV with >> 2000 watchers + POE/Event 2000 6328 109.99 751.67 14.02 via POE::Loop::Event + POE/Select 2000 6027 94.54 809.13 579.80 via POE::Loop::Select =head3 Discussion @@ -1749,6 +1789,42 @@ =back +=head1 SIGNALS + +AnyEvent currently installs handlers for these signals: + +=over 4 + +=item SIGCHLD + +A handler for C is installed by AnyEvent's child watcher +emulation for event loops that do not support them natively. Also, some +event loops install a similar handler. + +=item SIGPIPE + +A no-op handler is installed for C when C<$SIG{PIPE}> is C +when AnyEvent gets loaded. + +The rationale for this is that AnyEvent users usually do not really depend +on SIGPIPE delivery (which is purely an optimisation for shell use, or +badly-written programs), but C can cause spurious and rare +program exits as a lot of people do not expect C when writing to +some random socket. + +The rationale for installing a no-op handler as opposed to ignoring it is +that this way, the handler will be restored to defaults on exec. + +Feel free to install your own handler, or reset it to defaults. + +=back + +=cut + +$SIG{PIPE} = sub { } + unless defined $SIG{PIPE}; + + =head1 FORK Most event libraries are not fork-safe. The ones who are usually are