--- AnyEvent/lib/AnyEvent.pm 2008/10/30 03:43:14 1.188 +++ 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). @@ -863,7 +869,7 @@ use Carp; -our $VERSION = 4.31; +our $VERSION = 4.341; our $MODEL; our $AUTOLOAD; @@ -1006,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, ">") @@ -1045,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" @@ -1265,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 @@ -1538,7 +1571,7 @@ 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.14 0.75 0.99 pure perl implementation + 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