--- AnyEvent/lib/AnyEvent.pm 2009/07/17 23:12:20 1.243 +++ AnyEvent/lib/AnyEvent.pm 2009/07/28 02:07:18 1.259 @@ -1,9 +1,9 @@ =head1 NAME -AnyEvent - provide framework for multiple event loops +AnyEvent - the DBI of event loop programming -EV, Event, Glib, Tk, Perl, Event::Lib, Qt and POE are various supported -event loops. +EV, Event, Glib, Tk, Perl, Event::Lib, Irssi, rxvt-unicode, IO::Async, Qt +and POE are various supported event loops/environments. =head1 SYNOPSIS @@ -43,6 +43,14 @@ in a tutorial or some gentle introduction, have a look at the L manpage. +=head1 SUPPORT + +There is a mailinglist for discussing all things AnyEvent, and an IRC +channel, too. + +See the AnyEvent project page at the B, at L, for more info. + =head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) Glib, POE, IO::Async, Event... CPAN offers event models by the dozen @@ -370,8 +378,14 @@ so programs overwriting those signals directly will likely not work correctly. -Also note that many event loops (e.g. Glib, Tk, Qt, IO::Async) do not -support attaching callbacks to signals, which is a pity, as you cannot do +Example: exit on SIGINT + + my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 }); + +=head3 Signal Races, Delays and Workarounds + +Many event loops (e.g. Glib, Tk, Qt, IO::Async) do not support attaching +callbacks to signals in a generic way, which is a pity, as you cannot do race-free signal handling in perl. AnyEvent will try to do it's best, but in some cases, signals will be delayed. The maximum time a signal might be delayed is specified in C<$AnyEvent::MAX_SIGNAL_LATENCY> (default: 10 @@ -379,20 +393,20 @@ watcher is created, and should be left alone otherwise. Higher values will cause fewer spurious wake-ups, which is better for power and CPU saving. All these problems can be avoided by installing the optional -L module. - -Example: exit on SIGINT - - my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 }); +L module. This will not work with inherently broken +event loops such as L or L (and not with L +currently, as POE does it's own workaround with one-second latency). With +those, you just have to suffer the delays. =head2 CHILD PROCESS WATCHERS 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 triggered only when -the child process has finished and an exit status is available, not on -any trace events (stopped/continued). +The child process is specified by the C argument (one some backends, +using C<0> watches for any child process exit, on others this will +croak). The watcher will be 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 @@ -506,7 +520,8 @@ in time where multiple outstanding events have been processed. And yet another way to call them is transactions - each condition variable can be used to represent a transaction, which finishes at some point and delivers -a result. +a result. And yet some people know them as "futures" - a promise to +compute/deliver something that you can wait for. Condition variables are very useful to signal that something has finished, for example, if you write a module that does asynchronous http requests, @@ -784,6 +799,7 @@ AnyEvent::Impl::Tk based on Tk, very broken. AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse. AnyEvent::Impl::POE based on POE, very slow, some limitations. + AnyEvent::Impl::Irssi used when running within irssi. =item Backends with special needs. @@ -867,8 +883,25 @@ avoid autodetecting the event module at load time. If called in scalar or list context, then it creates and returns an object -that automatically removes the callback again when it is destroyed. See -L for a case where this is useful. +that automatically removes the callback again when it is destroyed (or +C when the hook was immediately executed). See L for +a case where this is useful. + +Example: Create a watcher for the IO::AIO module and store it in +C<$WATCHER>. Only do so after the event loop is initialised, though. + + our WATCHER; + + my $guard = AnyEvent::post_detect { + $WATCHER = AnyEvent->io (fh => IO::AIO::poll_fileno, poll => 'r', cb => \&IO::AIO::poll_cb); + }; + + # the ||= is important in case post_detect immediately runs the block, + # as to not clobber the newly-created watcher. assigning both watcher and + # post_detect guard to the same variable has the advantage of users being + # able to just C if the watcher causes them grief. + + $WATCHER ||= $guard; =item @AnyEvent::post_detect @@ -1055,7 +1088,7 @@ use Carp (); -our $VERSION = 4.83; +our $VERSION = 4.88; our $MODEL; our $AUTOLOAD; @@ -1090,14 +1123,15 @@ } my @models = ( - [EV:: => AnyEvent::Impl::EV::], - [Event:: => AnyEvent::Impl::Event::], - [AnyEvent::Impl::Perl:: => AnyEvent::Impl::Perl::], - # everything below here will not be autoprobed + [EV:: => AnyEvent::Impl::EV:: , 1], + [Event:: => AnyEvent::Impl::Event::, 1], + [AnyEvent::Impl::Perl:: => AnyEvent::Impl::Perl:: , 1], + # everything below here will not (normally) be autoprobed # as the pureperl backend should work everywhere # and is usually faster - [Glib:: => AnyEvent::Impl::Glib::], # becomes extremely slow with many watchers + [Glib:: => AnyEvent::Impl::Glib:: , 1], # becomes extremely slow with many watchers [Event::Lib:: => AnyEvent::Impl::EventLib::], # too buggy + [Irssi:: => AnyEvent::Impl::Irssi::], # Irssi has a bogus "Event" package [Tk:: => AnyEvent::Impl::Tk::], # crashes with many handles [Qt:: => AnyEvent::Impl::Qt::], # requires special main program [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza @@ -1107,9 +1141,9 @@ # byzantine signal and broken child handling, among others. # IO::Async is rather hard to detect, as it doesn't have any # obvious default class. -# [IO::Async:: => AnyEvent::Impl::IOAsync::], # requires special main program -# [IO::Async::Loop:: => AnyEvent::Impl::IOAsync::], # requires special main program -# [IO::Async::Notifier:: => AnyEvent::Impl::IOAsync::], # requires special main program +# [0, IO::Async:: => AnyEvent::Impl::IOAsync::], # requires special main program +# [0, IO::Async::Loop:: => AnyEvent::Impl::IOAsync::], # requires special main program +# [0, IO::Async::Notifier:: => AnyEvent::Impl::IOAsync::], # requires special main program ); our %method = map +($_ => 1), @@ -1123,7 +1157,7 @@ if ($MODEL) { $cb->(); - 1 + undef } else { push @post_detect, $cb; @@ -1165,15 +1199,17 @@ } unless ($MODEL) { - # try to load a model - + # try to autoload a model for (@REGISTRY, @models) { - my ($package, $model) = @$_; - if (eval "require $package" - and ${"$package\::VERSION"} > 0 - and eval "require $model") { + my ($package, $model, $autoload) = @$_; + if ( + $autoload + and eval "require $package" + and ${"$package\::VERSION"} > 0 + and eval "require $model" + ) { $MODEL = $model; - warn "AnyEvent: autoprobed model '$model', using it.\n" if $VERBOSE >= 2; + warn "AnyEvent: autoloaded model '$model', using it.\n" if $VERBOSE >= 2; last; } } @@ -1272,6 +1308,25 @@ } } +# install a dumym wakeupw atcher to reduce signal catching latency +sub _sig_add() { + unless ($SIG_COUNT++) { + # try to align timer on a full-second boundary, if possible + my $NOW = AnyEvent->now; + + $SIG_TW = AnyEvent->timer ( + after => $MAX_SIGNAL_LATENCY - ($NOW - int $NOW), + interval => $MAX_SIGNAL_LATENCY, + cb => sub { }, # just for the PERL_ASYNC_CHECK + ); + } +} + +sub _sig_del { + undef $SIG_TW + unless --$SIG_COUNT; +} + sub _signal { my (undef, %arg) = @_; @@ -1305,12 +1360,7 @@ # can't do signal processing without introducing races in pure perl, # so limit the signal latency. - ++$SIG_COUNT; - $SIG_TW ||= AnyEvent->timer ( - after => $MAX_SIGNAL_LATENCY, - interval => $MAX_SIGNAL_LATENCY, - cb => sub { }, # just for the PERL_ASYNC_CHECK - ); + _sig_add; } bless [$signal, $arg{cb}], "AnyEvent::Base::signal" @@ -1359,15 +1409,16 @@ sub AnyEvent::Base::signal::DESTROY { my ($signal, $cb) = @{$_[0]}; - undef $SIG_TW - unless --$SIG_COUNT; + _sig_del; delete $SIG_CB{$signal}{$cb}; - # delete doesn't work with older perls - they then - # print weird messages, or just unconditionally exit - # instead of getting the default action. - undef $SIG{$signal} + $HAVE_ASYNC_INTERRUPT + ? delete $SIG_ASY{$signal} + : # delete doesn't work with older perls - they then + # print weird messages, or just unconditionally exit + # instead of getting the default action. + undef $SIG{$signal} unless keys %{ $SIG_CB{$signal} }; } @@ -1378,12 +1429,19 @@ our $CHLD_DELAY_W; our $WNOHANG; +sub _emit_childstatus($$) { + my (undef, $rpid, $rstatus) = @_; + + $_->($rpid, $rstatus) + for values %{ $PID_CB{$rpid} || {} }, + values %{ $PID_CB{0} || {} }; +} + sub _sigchld { - while (0 < (my $pid = waitpid -1, $WNOHANG)) { - $_->($pid, $?) - for values %{ $PID_CB{$pid} || {} }, - values %{ $PID_CB{0} || {} }; - } + my $pid; + + AnyEvent->_emit_childstatus ($pid, $?) + while ($pid = waitpid -1, $WNOHANG) > 0; } sub child { @@ -1568,6 +1626,9 @@ When set to C<2> or higher, cause AnyEvent to report to STDERR which event model it chooses. +When set to C<8> or higher, then AnyEvent will report extra information on +which optional modules it loads and how it implements certain features. + =item C AnyEvent does not do much argument checking by default, as thorough @@ -1654,6 +1715,11 @@ variables exist, they will be used to specify CA certificate locations instead of a system-dependent default. +=item C and C + +When these are set to C<1>, then the respective modules are not +loaded. Mostly good for testing AnyEvent itself. + =back =head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE @@ -2249,7 +2315,7 @@ my knowledge, there is no way to do completely race-free and quick signal handling in pure perl. To ensure that signals still get delivered, AnyEvent will start an interval timer to wake up perl (and -catch the signals) with soemd elay (default is 10 seconds, look for +catch the signals) with some delay (default is 10 seconds, look for C<$AnyEvent::MAX_SIGNAL_LATENCY>). If this module is available, then it will be used to implement signal @@ -2260,6 +2326,11 @@ This affects not just the pure-perl event loop, but also other event loops that have no signal handling on their own (e.g. Glib, Tk, Qt). +Some event loops (POE, Event, Event::Lib) offer signal watchers natively, +and either employ their own workarounds (POE) or use AnyEvent's workaround +(using C<$AnyEvent::MAX_SIGNAL_LATENCY>). Installing L +does nothing for those backends. + =item L This module isn't really "optional", as it is simply one of the backend @@ -2282,7 +2353,7 @@ This module is required when you want to read or write JSON data via L. It is also written in pure-perl, but can take -advantage of the ulta-high-speed L module when it is installed. +advantage of the ultra-high-speed L module when it is installed. In fact, L will use L by default if it is installed. @@ -2359,7 +2430,7 @@ Implementations: L, L, L, L, L, L, L, -L, L. +L, L, L. Non-blocking file handles, sockets, TCP clients and servers: L, L, L.