--- AnyEvent/lib/AnyEvent.pm 2008/05/01 12:35:54 1.105 +++ AnyEvent/lib/AnyEvent.pm 2008/05/10 20:30:35 1.113 @@ -2,7 +2,7 @@ AnyEvent - provide framework for multiple event loops -EV, Event, Coro::EV, Coro::Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event loops +EV, Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event loops =head1 SYNOPSIS @@ -17,8 +17,8 @@ }); my $w = AnyEvent->condvar; # stores whether a condition was flagged - $w->wait; # enters "main loop" till $condvar gets ->broadcast - $w->broadcast; # wake up current and all future wait's + $w->wait; # enters "main loop" till $condvar gets ->send + $w->send; # wake up current and all future wait's =head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) @@ -80,7 +80,7 @@ During the first call of any watcher-creation method, the module tries to detect the currently loaded event loop by probing whether one of the -following modules is already loaded: L, L, L, +following modules is already loaded: L, L, L, L, L, L, L, L. The first one found is used. If none are found, the module tries to load these modules (excluding Tk, Event::Lib, Qt and POE as the pure perl @@ -290,7 +290,7 @@ cb => sub { my ($pid, $status) = @_; warn "pid $pid exited with status $status"; - $done->broadcast; + $done->send; }, ); @@ -315,7 +315,7 @@ becomes true. After creation, the conditon variable is "false" until it becomes "true" -by calling the C method. +by calling the C method. Condition variables are similar to callbacks, except that you can optionally wait for them. They can also be called merge points - points @@ -333,7 +333,7 @@ You can also use them to simulate traditional event loops - for example, you can block your main program until an event occurs - for example, you could C<< ->wait >> in your main program until the user clicks the Quit -button of your app, which would C<< ->broadcast >> the "quit" event. +button of your app, which would C<< ->send >> the "quit" event. Note that condition variables recurse into the event loop - if you have two pieces of code that call C<< ->wait >> in a round-robbin fashion, you @@ -348,8 +348,8 @@ it's C method in your own C method. There are two "sides" to a condition variable - the "producer side" which -eventually calls C<< -> broadcast >>, and the "consumer side", which waits -for the broadcast to occur. +eventually calls C<< -> send >>, and the "consumer side", which waits +for the send to occur. Example: @@ -357,42 +357,42 @@ my $result_ready = AnyEvent->condvar; # do something such as adding a timer - # or socket watcher the calls $result_ready->broadcast + # or socket watcher the calls $result_ready->send # when the "result" is ready. # in this case, we simply use a timer: my $w = AnyEvent->timer ( after => 1, - cb => sub { $result_ready->broadcast }, + cb => sub { $result_ready->send }, ); # this "blocks" (while handling events) till the callback - # calls broadcast + # calls send $result_ready->wait; =head3 METHODS FOR PRODUCERS These methods should only be used by the producing side, i.e. the -code/module that eventually broadcasts the signal. Note that it is also +code/module that eventually sends the signal. Note that it is also the producer side which creates the condvar in most cases, but it isn't uncommon for the consumer to create it as well. =over 4 -=item $cv->broadcast (...) +=item $cv->send (...) Flag the condition as ready - a running C<< ->wait >> and all further calls to C will (eventually) return after this method has been -called. If nobody is waiting the broadcast will be remembered. +called. If nobody is waiting the send will be remembered. If a callback has been set on the condition variable, it is called -immediately from within broadcast. +immediately from within send. -Any arguments passed to the C call will be returned by all +Any arguments passed to the C call will be returned by all future C<< ->wait >> calls. =item $cv->croak ($error) -Similar to broadcast, but causes all call's wait C<< ->wait >> to invoke +Similar to send, but causes all call's wait C<< ->wait >> to invoke C with the given error message/object/scalar. This can be used to signal any errors to the condition variable @@ -409,15 +409,15 @@ Every call to C<< ->begin >> will increment a counter, and every call to C<< ->end >> will decrement it. If the counter reaches C<0> in C<< ->end >>, the (last) callback passed to C will be executed. That callback -is I to call C<< ->broadcast >>, but that is not required. If no -callback was set, C will be called without any arguments. +is I to call C<< ->send >>, but that is not required. If no +callback was set, C will be called without any arguments. Let's clarify this with the ping example: my $cv = AnyEvent->condvar; my %result; - $cv->begin (sub { $cv->broadcast (\%result) }); + $cv->begin (sub { $cv->send (\%result) }); for my $host (@list_of_hosts) { $cv->begin; @@ -430,7 +430,7 @@ $cv->end; This code fragment supposedly pings a number of hosts and calls -C after results for all then have have been gathered - in any +C after results for all then have have been gathered - in any order. To achieve this, the code issues a call to C when it starts each ping request and calls C when it has received some result for it. Since C and C only maintain a counter, the order in which @@ -439,7 +439,7 @@ There is an additional bracketing call to C and C outside the loop, which serves two important purposes: first, it sets the callback to be called once the counter reaches C<0>, and second, it ensures that -broadcast is called even when C hosts are being pinged (the loop +C is called even when C hosts are being pinged (the loop doesn't execute once). This is the general pattern when you "fan out" into multiple subrequests: @@ -454,9 +454,11 @@ These methods should only be used by the consuming side, i.e. the code awaits the condition. +=over 4 + =item $cv->wait -Wait (blocking if necessary) until the C<< ->broadcast >> or C<< ->croak +Wait (blocking if necessary) until the C<< ->send >> or C<< ->croak >> methods have been called on c<$cv>, while servicing other watchers normally. @@ -466,7 +468,7 @@ If an error condition has been set by calling C<< ->croak >>, then this function will call C. -In list context, all parameters passed to C will be returned, +In list context, all parameters passed to C will be returned, in scalar context only the first one will be returned. Not all event models support a blocking wait - some die in that case @@ -480,15 +482,33 @@ 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 L and -L explicitly support concurrent C<< ->wait >>'s -from different coroutines, however). +can supply. + +The L module, however, I and I supply coroutines and, in +fact, L replaces AnyEvent's condvars by coroutine-safe +versions and also integrates coroutines into AnyEvent, making blocking +C<< ->wait >> calls perfectly safe as long as they are done from another +coroutine (one that doesn't run the event loop). You can ensure that C<< -wait >> never blocks by setting a callback and only calling C<< ->wait >> from within that callback (or at a later time). This will work even when the event loop does not support blocking waits otherwise. +=item $bool = $cv->ready + +Returns true when the condition is "true", i.e. whether C or +C have been called. + +=item $cb = $cv->cb ([new callback]) + +This is a mutator function that returns the callback set and optionally +replaces it before doing so. + +The callback will be called when the condition becomes "true", i.e. when +C or C are called. Calling C inside the callback +or at any later time is guaranteed not to block. + =back =head1 GLOBAL VARIABLES AND FUNCTIONS @@ -505,8 +525,6 @@ The known classes so far are: - 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, best choice). AnyEvent::Impl::Event based on Event, second best choice. AnyEvent::Impl::Perl pure-perl implementation, fast and portable. @@ -533,6 +551,27 @@ have created an AnyEvent watcher anyway, that is, as late as possible at runtime. +=item $guard = AnyEvent::post_detect { BLOCK } + +Arranges for the code block to be executed as soon as the event model is +autodetected (or immediately if this has already happened). + +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. + +=item @AnyEvent::post_detect + +If there are any code references in this array (you can C to it +before or after loading AnyEvent), then they will called directly after +the event loop has been chosen. + +You should check C<$AnyEvent::MODEL> before adding to this array, though: +if it contains a true value then the event loop has already been detected, +and the array will be ignored. + +Best use C instead. + =back =head1 WHAT TO DO IN A MODULE @@ -546,7 +585,7 @@ to load the event module first. Never call C<< ->wait >> on a condition variable unless you I that -the C<< ->broadcast >> method has been called on it already. This is +the C<< ->send >> method has been called on it already. This is because it will stall the whole program, and the whole point of using events is to stay interactive. @@ -594,10 +633,6 @@ Provide read and write buffers and manages watchers for reads and writes. -=item L - -Provides a means to do non-blocking connects, accepts etc. - =item L Provides a simple web application server framework. @@ -630,21 +665,22 @@ =item L -Has special support for AnyEvent. +Has special support for AnyEvent via L. -=item L +=item L, L -The lambda approach to I/O - don't ask, look there. Can use AnyEvent. +Truly asynchronous I/O, should be in the toolbox of every event +programmer. AnyEvent::AIO transparently fuses IO::AIO and AnyEvent +together. -=item L +=item L, L -Truly asynchronous I/O, should be in the toolbox of every event -programmer. Can be trivially made to use AnyEvent. +Truly asynchronous Berkeley DB access. AnyEvent::AIO transparently fuses +IO::AIO and AnyEvent together. -=item L +=item L -Truly asynchronous Berkeley DB access. Can be trivially made to use -AnyEvent. +The lambda approach to I/O - don't ask, look there. Can use AnyEvent. =back @@ -657,7 +693,7 @@ use Carp; -our $VERSION = '3.3'; +our $VERSION = '3.4'; our $MODEL; our $AUTOLOAD; @@ -668,8 +704,6 @@ our @REGISTRY; my @models = ( - [Coro::EV:: => AnyEvent::Impl::CoroEV::], - [Coro::Event:: => AnyEvent::Impl::CoroEvent::], [EV:: => AnyEvent::Impl::EV::], [Event:: => AnyEvent::Impl::Event::], [Tk:: => AnyEvent::Impl::Tk::], @@ -683,7 +717,29 @@ [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza ); -our %method = map +($_ => 1), qw(io timer signal child condvar broadcast wait one_event DESTROY); +our %method = map +($_ => 1), qw(io timer signal child condvar one_event DESTROY); + +our @post_detect; + +sub post_detect(&) { + my ($cb) = @_; + + if ($MODEL) { + $cb->(); + + 1 + } else { + push @post_detect, $cb; + + defined wantarray + ? bless \$cb, "AnyEvent::Util::Guard" + : () + } +} + +sub AnyEvent::Util::Guard::DESTROY { + @post_detect = grep $_ != ${$_[0]}, @post_detect; +} sub detect() { unless ($MODEL) { @@ -727,12 +783,14 @@ } $MODEL - 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) or Glib."; + or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: EV, Event or Glib."; } } unshift @ISA, $MODEL; push @{"$MODEL\::ISA"}, "AnyEvent::Base"; + + (shift @post_detect)->() while @post_detect; } $MODEL @@ -1376,17 +1434,22 @@ use AnyEvent; +Similar considerations apply to $ENV{PERL_ANYEVENT_VERBOSE}, as that can +be used to probe what backend is used and gain other information (which is +probably even less useful to an attacker than PERL_ANYEVENT_MODEL). + =head1 SEE ALSO -Event modules: L, L, L, L, -L, L, L, L, L, L, -L, L, L. - -Implementations: L, L, -L, L, L, -L, L, L, -L, L. +Event modules: L, L, L, L, L, +L, L, L, L, L. + +Implementations: L, L, +L, L, L, +L, L, +L. + +Coroutine support: L, L, L, L, Nontrivial usage examples: L, L.