--- AnyEvent/lib/AnyEvent.pm 2008/10/28 08:07:04 1.187 +++ AnyEvent/lib/AnyEvent.pm 2009/04/01 15:29:00 1.202 @@ -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). @@ -164,11 +170,17 @@ You can create an I/O watcher by calling the C<< AnyEvent->io >> method with the following mandatory key-value pairs as arguments: -C the Perl I (I file descriptor) to watch for events -(AnyEvent might or might not keep a reference to this file handle). C -must be a string that is either C or C, which creates a watcher -waiting for "r"eadable or "w"ritable events, respectively. C is the -callback to invoke each time the file handle becomes ready. +C is the Perl I (I file descriptor) to watch +for events (AnyEvent might or might not keep a reference to this file +handle). Note that only file handles pointing to things for which +non-blocking operation makes sense are allowed. This includes sockets, +most character devices, pipes, fifos and so on, but not for example files +or block devices. + +C must be a string that is either C or C, which creates a +watcher waiting for "r"eadable or "w"ritable events, respectively. + +C is the callback to invoke each time the file handle becomes ready. Although the callback might get passed parameters, their value and presence is undefined and you cannot rely on them. Portable AnyEvent @@ -863,7 +875,7 @@ use Carp; -our $VERSION = 4.3; +our $VERSION = 4.35; our $MODEL; our $AUTOLOAD; @@ -1006,8 +1018,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 +1055,55 @@ # default implementation for ->signal -our %SIG_CB; +our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); + +sub _signal_exec { + sysread $SIGPIPE_R, my $dummy, 4; + + while (%SIG_EV) { + for (keys %SIG_EV) { + delete $SIG_EV{$_}; + $_->() for values %{ $SIG_CB{$_} || {} }; + } + } +} sub signal { my (undef, %arg) = @_; + unless ($SIGPIPE_R) { + require Fcntl; + + if (AnyEvent::WIN32) { + require AnyEvent::Util; + + ($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; + 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"; + + # not strictly required, as $^F is normally 2, but let's make sure... + fcntl $SIGPIPE_R, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC; + fcntl $SIGPIPE_W, &Fcntl::F_SETFD, &Fcntl::FD_CLOEXEC; + + $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} || {} }; + local $!; + syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; + undef $SIG_EV{$signal}; }; bless [$signal, $arg{cb}], "AnyEvent::Base::Signal" @@ -1265,7 +1313,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 +1586,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 @@ -1829,7 +1877,7 @@ Perl 5.8 has numerous memleaks that sometimes hit this module and are hard to work around. If you suffer from memleaks, first upgrade to Perl 5.10 and check wether the leaks still show up. (Perl 5.10.0 has other annoying -mamleaks, such as leaking on C and C but it is usually not as +memleaks, such as leaking on C and C but it is usually not as pronounced).