--- AnyEvent/lib/AnyEvent.pm 2006/12/10 21:33:33 1.18 +++ AnyEvent/lib/AnyEvent.pm 2008/04/16 14:04:45 1.50 @@ -2,7 +2,7 @@ AnyEvent - provide framework for multiple event loops -Event, Coro, Glib, Tk, Perl - various supported event loops +EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl - various supported event loops =head1 SYNOPSIS @@ -20,6 +20,51 @@ $w->wait; # enters "main loop" till $condvar gets ->broadcast $w->broadcast; # wake up current and all future wait's +=head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) + +Glib, POE, IO::Async, Event... CPAN offers event models by the dozen +nowadays. So what is different about AnyEvent? + +Executive Summary: AnyEvent is I, AnyEvent is I and AnyEvent is I. + +First and foremost, I itself, it only +interfaces to whatever event model the main program happens to use in a +pragmatic way. For event models and certain classes of immortals alike, +the statement "there can only be one" is a bitter reality, and AnyEvent +helps hiding the differences. + +The goal of AnyEvent is to offer module authors the ability to do event +programming (waiting for I/O or timer events) without subscribing to a +religion, a way of living, and most importantly: without forcing your +module users into the same thing by forcing them to use the same event +model you use. + +For modules like POE or IO::Async (which is actually doing all I/O +I...), using them in your module is like joining a +cult: After you joined, you are dependent on them and you cannot use +anything else, as it is simply incompatible to everything that isn't +itself. + +AnyEvent + POE works fine. AnyEvent + Glib works fine. AnyEvent + Tk +works fine etc. etc. but none of these work together with the rest: POE ++ IO::Async? no go. Tk + Event? no go. If your module uses one of +those, every user of your module has to use it, too. If your module +uses AnyEvent, it works transparently with all event models it supports +(including stuff like POE and IO::Async). + +In addition of being free of having to use I, AnyEvent also is free of bloat and policy: with POE or similar +modules, you get an enourmous amount of code and strict rules you have +to follow. AnyEvent, on the other hand, is lean and to the point by only +offering the functionality that is useful, in as thin as a wrapper as +technically possible. + +Of course, if you want lots of policy (this can arguably be somewhat +useful) and you want to force your users to use the one and only event +model, you should I use this module. + + =head1 DESCRIPTION L provides an identical interface to multiple event loops. This @@ -32,11 +77,11 @@ On the first call of any method, the module tries to detect the currently loaded event loop by probing wether any of the following modules is -loaded: L, L, L, L. The first one found is -used. If none is found, the module tries to load these modules in the -order given. The first one that could be successfully loaded will be -used. If still none could be found, AnyEvent will fall back to a pure-perl -event loop, which is also not very efficient. +loaded: L, L, L, L, L, L. The +first one found is used. If none are found, the module tries to load these +modules in the order given. The first one that could be successfully +loaded will be used. If still none could be found, AnyEvent will fall back +to a pure-perl event loop, which is also not very efficient. Because AnyEvent first checks for modules that are already loaded, loading an Event model explicitly before first using AnyEvent will likely make @@ -72,13 +117,9 @@ C the Perl I (not filedescriptor) to watch for events. C must be a string that is either C or C, that creates -a watcher waiting for "r"eadable or "w"ritable events. C teh callback +a watcher waiting for "r"eadable or "w"ritable events. C the callback to invoke everytime the filehandle becomes ready. -Only one io watcher per C and C combination is allowed (i.e. on -a socket you can have one r + one w, not any more (limitation comes from -Tk - if you are sure you are not using Tk this limitation is gone). - Filehandles will be kept alive, so as long as the watcher exists, the filehandle exists, too. @@ -91,9 +132,9 @@ undef $w; }); -=head2 TIMER WATCHERS +=head2 TIME WATCHERS -You can create a timer watcher by calling the C<< AnyEvent->timer >> +You can create a time watcher by calling the C<< AnyEvent->timer >> method with the following mandatory arguments: C after how many seconds (fractions are supported) should the timer @@ -111,7 +152,7 @@ }); # to cancel the timer: - undef $w + undef $w; =head2 CONDITION WATCHERS @@ -121,6 +162,12 @@ A condition watcher watches for a condition - precisely that the C<< ->broadcast >> method has been called. +Note that condition watchers recurse into the event loop - if you have +two watchers that call C<< ->wait >> in a round-robbin fashion, you +lose. Therefore, condition watchers are good to export to your caller, but +you should avoid making a blocking wait, at least in callbacks, as this +usually asks for trouble. + The watcher has only two methods: =over 4 @@ -130,16 +177,24 @@ Wait (blocking if necessary) until the C<< ->broadcast >> method has been called on c<$cv>, while servicing other watchers normally. -Not all event models support a blocking wait - some die in that case, so -if you are using this from a module, never require a blocking wait, but -let the caller decide wether the call will block or not (for example, -by coupling condition variables with some kind of request results and -supporting callbacks so the caller knows that getting the result will not -block, while still suppporting blockign waits if the caller so desires). - You can only wait once on a condition - additional calls will return immediately. +Not all event models support a blocking wait - some die in that case +(programs might want to do that so they stay interactive), so I, but let the +caller decide wether the call will block or not (for example, by coupling +condition variables with some kind of request results and supporting +callbacks so the caller knows that getting the result will not block, +while still suppporting blocking waits if the caller so desires). + +Another reason I to C<< ->wait >> in a module is that you cannot +sensibly have two C<< ->wait >>'s in parallel, as that would require +multiple interpreters or coroutines/threads, none of which C +can supply (the coroutine-aware backends C and C +explicitly support concurrent C<< ->wait >>'s from different coroutines, +however). + =item $cv->broadcast Flag the condition as ready - a running C<< ->wait >> and all further @@ -159,6 +214,32 @@ =back +=head2 SIGNAL WATCHERS + +You can listen for signals using a signal watcher, C is the signal +I without any C prefix. Multiple signals events can be clumped +together into one callback invocation, and callback invocation might or +might not be asynchronous. + +These watchers might use C<%SIG>, so programs overwriting those signals +directly will likely not work correctly. + +Example: exit on SIGINT + + my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 }); + +=head2 CHILD PROCESS WATCHERS + +You can also listen for the status of a child process specified by the +C argument (or any child if the pid argument is 0). 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). + +Example: wait for pid 1333 + + my $w = AnyEvent->child (pid => 1333, cb => sub { warn "exit status $?" }); + =head1 GLOBALS =over 4 @@ -173,11 +254,19 @@ The known classes so far are: - AnyEvent::Impl::Coro based on Coro::Event, best choise. - AnyEvent::Impl::Event based on Event, also best choice :) - AnyEvent::Impl::Glib based on Glib, second-best choice. + AnyEvent::Impl::CoroEV based on Coro::EV, best choice. + AnyEvent::Impl::CoroEvent based on Coro::Event, second best choice. + AnyEvent::Impl::EV based on EV (an interface to libev, also best choice). + AnyEvent::Impl::Event based on Event, also second best choice :) + AnyEvent::Impl::Glib based on Glib, third-best choice. AnyEvent::Impl::Tk based on Tk, very bad choice. - AnyEvent::Impl::Perl pure-perl implementation, inefficient. + AnyEvent::Impl::Perl pure-perl implementation, inefficient but portable. + +=item AnyEvent::detect + +Returns C<$AnyEvent::MODEL>, forcing autodetection of the event model if +necessary. You should only call this function right before you would have +created an AnyEvent watcher anyway, that is, very late at runtime. =back @@ -216,10 +305,11 @@ package AnyEvent; no warnings; -use strict 'vars'; +use strict; + use Carp; -our $VERSION = '2.1'; +our $VERSION = '3.0'; our $MODEL; our $AUTOLOAD; @@ -230,22 +320,21 @@ our @REGISTRY; my @models = ( - [Coro::Event:: => AnyEvent::Impl::Coro::], + [Coro::EV:: => AnyEvent::Impl::CoroEV::], + [Coro::Event:: => AnyEvent::Impl::CoroEvent::], + [EV:: => AnyEvent::Impl::EV::], [Event:: => AnyEvent::Impl::Event::], [Glib:: => AnyEvent::Impl::Glib::], [Tk:: => AnyEvent::Impl::Tk::], [AnyEvent::Impl::Perl:: => AnyEvent::Impl::Perl::], ); -our %method = map +($_ => 1), qw(io timer condvar broadcast wait DESTROY); - -sub AUTOLOAD { - (my $func = $AUTOLOAD) =~ s/.*://; - - $method{$func} - or croak "$func: not a valid method for AnyEvent objects"; +our %method = map +($_ => 1), qw(io timer condvar broadcast wait signal one_event DESTROY); +sub detect() { unless ($MODEL) { + no strict 'refs'; + # check for already loaded models for (@REGISTRY, @models) { my ($package, $model) = @$_; @@ -263,7 +352,9 @@ for (@REGISTRY, @models) { my ($package, $model) = @$_; - if (eval "require $model") { + if (eval "require $package" + and ${"$package\::VERSION"} > 0 + and eval "require $model") { $MODEL = $model; warn "AnyEvent: autoprobed and loaded model '$model', using it.\n" if $verbose > 1; last; @@ -271,16 +362,125 @@ } $MODEL - or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: Coro, Event, Glib or Tk."; + or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: EV (or Coro+EV), Event (or Coro+Event), Glib or Tk."; } + + unshift @ISA, $MODEL; + push @{"$MODEL\::ISA"}, "AnyEvent::Base"; } - @ISA = $MODEL; + $MODEL +} + +sub AUTOLOAD { + (my $func = $AUTOLOAD) =~ s/.*://; + + $method{$func} + or croak "$func: not a valid method for AnyEvent objects"; + + detect unless $MODEL; my $class = shift; $class->$func (@_); } +package AnyEvent::Base; + +# default implementation for ->condvar, ->wait, ->broadcast + +sub condvar { + bless \my $flag, "AnyEvent::Base::CondVar" +} + +sub AnyEvent::Base::CondVar::broadcast { + ${$_[0]}++; +} + +sub AnyEvent::Base::CondVar::wait { + AnyEvent->one_event while !${$_[0]}; +} + +# default implementation for ->signal + +our %SIG_CB; + +sub signal { + my (undef, %arg) = @_; + + 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} || {} }; + }; + + bless [$signal, $arg{cb}], "AnyEvent::Base::Signal" +} + +sub AnyEvent::Base::Signal::DESTROY { + my ($signal, $cb) = @{$_[0]}; + + delete $SIG_CB{$signal}{$cb}; + + $SIG{$signal} = 'DEFAULT' unless keys %{ $SIG_CB{$signal} }; +} + +# default implementation for ->child + +our %PID_CB; +our $CHLD_W; +our $CHLD_DELAY_W; +our $PID_IDLE; +our $WNOHANG; + +sub _child_wait { + while (0 < (my $pid = waitpid -1, $WNOHANG)) { + $_->($pid, $?) for (values %{ $PID_CB{$pid} || {} }), + (values %{ $PID_CB{0} || {} }); + } + + undef $PID_IDLE; +} + +sub _sigchld { + # make sure we deliver these changes "synchronous" with the event loop. + $CHLD_DELAY_W ||= AnyEvent->timer (after => 0, cb => sub { + undef $CHLD_DELAY_W; + &_child_wait; + }); +} + +sub child { + my (undef, %arg) = @_; + + defined (my $pid = $arg{pid} + 0) + or Carp::croak "required option 'pid' is missing"; + + $PID_CB{$pid}{$arg{cb}} = $arg{cb}; + + unless ($WNOHANG) { + $WNOHANG = eval { require POSIX; &POSIX::WNOHANG } || 1; + } + + unless ($CHLD_W) { + $CHLD_W = AnyEvent->signal (signal => 'CHLD', cb => \&_sigchld); + # child could be a zombie already, so make at least one round + &_sigchld; + } + + bless [$pid, $arg{cb}], "AnyEvent::Base::Child" +} + +sub AnyEvent::Base::Child::DESTROY { + my ($pid, $cb) = @{$_[0]}; + + delete $PID_CB{$pid}{$cb}; + delete $PID_CB{$pid} unless keys %{ $PID_CB{$pid} }; + + undef $CHLD_W unless keys %PID_CB; +} + =head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE If you need to support another event library which isn't directly @@ -299,7 +499,7 @@ AnyEvent is loaded and asked to find a suitable event model, it will first check for the presence of urxvt. -The class should prove implementations for all watcher types (see +The class should provide implementations for all watcher types (see L (source code), L (Source code) and so on for actual examples, use C to see the sources). @@ -313,7 +513,7 @@ I also cheats a bit by not providing blocking access to condition variables: code blocking while waiting for a condition will C. This still works with most modules/usages, and blocking calls must -not be in an interactive appliation, so it makes sense. +not be in an interactive application, so it makes sense. =head1 ENVIRONMENT VARIABLES @@ -440,7 +640,7 @@ my $data = $fcp->client_get ($url); -2. Blocking, but parallelizing: +2. Blocking, but running in parallel: my @datas = map $_->result, map $fcp->txn_client_get ($_), @@ -449,9 +649,9 @@ Both blocking examples work without the module user having to know anything about events. -3a. Event-based in a main program, using any support Event module: +3a. Event-based in a main program, using any supported event module: - use Event; + use EV; $fcp->txn_client_get ($url)->cb (sub { my $txn = shift; @@ -459,7 +659,7 @@ ... }); - Event::loop; + EV::loop; 3b. The module user could use AnyEvent, too: @@ -476,11 +676,14 @@ =head1 SEE ALSO -Event modules: L, L, L, L, L. +Event modules: L, L, L, L, +L, L, L, L, L, L. -Implementations: L, L, L, L. +Implementations: L, L, +L, L, +L, L, L. -Nontrivial usage example: L. +Nontrivial usage examples: L, L. =head1