--- AnyEvent/lib/AnyEvent.pm 2008/05/01 12:35:54 1.105 +++ AnyEvent/lib/AnyEvent.pm 2008/05/23 23:37:13 1.125 @@ -1,8 +1,8 @@ -=head1 NAME +=head1 => NAME 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->send; # wake up current and all future recv's + $w->recv; # enters "main loop" till $condvar gets ->send =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 @@ -281,8 +281,6 @@ my $done = AnyEvent->condvar; - AnyEvent::detect; # force event module to be initialised - my $pid = fork or exit 5; my $w = AnyEvent->child ( @@ -290,12 +288,12 @@ cb => sub { my ($pid, $status) = @_; warn "pid $pid exited with status $status"; - $done->broadcast; + $done->send; }, ); # do something else, then wait for process exit - $done->wait; + $done->recv; =head2 CONDITION VARIABLES @@ -315,7 +313,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 @@ -328,15 +326,15 @@ for example, if you write a module that does asynchronous http requests, then a condition variable would be the ideal candidate to signal the availability of results. The user can either act when the callback is -called or can synchronously C<< ->wait >> for the results. +called or can synchronously C<< ->recv >> for the results. 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. +could C<< ->recv >> in your main program until the user clicks the Quit +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 +two pieces of code that call C<< ->recv >> in a round-robbin fashion, you lose. Therefore, condition variables are good to export to your caller, but you should avoid making a blocking wait yourself, at least in callbacks, as this asks for trouble. @@ -348,8 +346,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 +355,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 - $result_ready->wait; + # calls send + $result_ready->recv; =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. +Flag the condition as ready - a running C<< ->recv >> and all further +calls to C will (eventually) return after this method has been +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 -future C<< ->wait >> calls. +Any arguments passed to the C call will be returned by all +future C<< ->recv >> 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 to C<< ->recv >> to invoke C with the given error message/object/scalar. This can be used to signal any errors to the condition variable @@ -402,6 +400,8 @@ =item $cv->end +These two methods are EXPERIMENTAL and MIGHT CHANGE. + These two methods can be used to combine many transactions/events into one. For example, a function that pings many hosts in parallel might want to use a condition variable for the whole process. @@ -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. -=item $cv->wait +=over 4 -Wait (blocking if necessary) until the C<< ->broadcast >> or C<< ->croak +=item $cv->recv + +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 @@ -477,18 +479,36 @@ 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 +Another reason I to C<< ->recv >> in a module is that you cannot +sensibly have two C<< ->recv >>'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<< ->recv >> 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 +You can ensure that C<< -recv >> never blocks by setting a callback and +only calling C<< ->recv >> 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 @@ -545,14 +584,14 @@ by calling AnyEvent in your module body you force the user of your module 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 +Never call C<< ->recv >> on a condition variable unless you I that +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. -It is fine, however, to call C<< ->wait >> when the user of your module +It is fine, however, to call C<< ->recv >> when the user of your module requests it (i.e. if you create a http request object ad have a method -called C that returns the results, it should call C<< ->wait >> +called C that returns the results, it should call C<< ->recv >> freely, as the user of your module knows what she is doing. always). =head1 WHAT TO DO IN THE MAIN PROGRAM @@ -596,7 +635,9 @@ =item L -Provides a means to do non-blocking connects, accepts etc. +Provides various utility functions for (internet protocol) sockets, +addresses and name resolution. Also functions to create non-blocking tcp +connections or tcp servers, with IPv6 and SRV record support and more. =item L @@ -604,8 +645,7 @@ =item L -Provides asynchronous DNS resolver capabilities, beyond what -L offers. +Provides rich asynchronous DNS resolver capabilities. =item L @@ -630,21 +670,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 +698,7 @@ use Carp; -our $VERSION = '3.3'; +our $VERSION = '3.6'; our $MODEL; our $AUTOLOAD; @@ -668,8 +709,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 +722,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::PostDetect" + : () + } +} + +sub AnyEvent::Util::PostDetect::DESTROY { + @post_detect = grep $_ != ${$_[0]}, @post_detect; +} sub detect() { unless ($MODEL) { @@ -727,12 +788,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 @@ -752,18 +815,10 @@ package AnyEvent::Base; -# default implementation for ->condvar, ->wait, ->broadcast +# default implementation for ->condvar sub condvar { - bless \my $flag, "AnyEvent::Base::CondVar" -} - -sub AnyEvent::Base::CondVar::broadcast { - ${$_[0]}++; -} - -sub AnyEvent::Base::CondVar::wait { - AnyEvent->one_event while !${$_[0]}; + bless { @_ == 3 ? (_ae_cb => $_[2]) : () }, AnyEvent::CondVar:: } # default implementation for ->signal @@ -847,6 +902,62 @@ undef $CHLD_W unless keys %PID_CB; } +package AnyEvent::CondVar; + +our @ISA = AnyEvent::CondVar::Base::; + +package AnyEvent::CondVar::Base; + +sub _send { + # nop +} + +sub send { + my $cv = shift; + $cv->{_ae_sent} = [@_]; + (delete $cv->{_ae_cb})->($cv) if $cv->{_ae_cb}; + $cv->_send; +} + +sub croak { + $_[0]{_ae_croak} = $_[1]; + $_[0]->send; +} + +sub ready { + $_[0]{_ae_sent} +} + +sub _wait { + AnyEvent->one_event while !$_[0]{_ae_sent}; +} + +sub recv { + $_[0]->_wait; + + Carp::croak $_[0]{_ae_croak} if $_[0]{_ae_croak}; + wantarray ? @{ $_[0]{_ae_sent} } : $_[0]{_ae_sent}[0] +} + +sub cb { + $_[0]{_ae_cb} = $_[1] if @_ > 1; + $_[0]{_ae_cb} +} + +sub begin { + ++$_[0]{_ae_counter}; + $_[0]{_ae_end_cb} = $_[1] if @_ > 1; +} + +sub end { + return if --$_[0]{_ae_counter}; + &{ $_[0]{_ae_end_cb} || sub { $_[0]->send } }; +} + +# undocumented/compatibility with pre-3.4 +*broadcast = \&send; +*wait = \&_wait; + =head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE This is an advanced topic that you do not normally need to use AnyEvent in @@ -925,6 +1036,23 @@ PERL_ANYEVENT_MODEL=Perl perl ... +=item C + +Used by both L and L to determine preferences +for IPv4 or IPv6. The default is unspecified (and might change, or be the result +of autoprobing). + +Must be set to a comma-separated list of protocols or address families, +current supported: C and C. Only protocols mentioned will be +used, and preference will be given to protocols mentioned earlier in the +list. + +Examples: C - prefer IPv4 over IPv6, +but support both and try to use both. C +- only support IPv4, never try to resolve or contact IPv6 +addressses. C support either IPv4 or +IPv6, but prefer IPv6 over IPv4. + =back =head1 EXAMPLE PROGRAM @@ -944,7 +1072,7 @@ warn "io event <$_[0]>\n"; # will always output chomp (my $input = ); # read a line warn "read: $input\n"; # output what has been read - $cv->broadcast if $input =~ /^q/i; # quit program if /^q/i + $cv->send if $input =~ /^q/i; # quit program if /^q/i }, ); @@ -959,7 +1087,7 @@ new_timer; # create first timer - $cv->wait; # wait until user enters /^q/i + $cv->recv; # wait until user enters /^q/i =head1 REAL-WORLD EXAMPLE @@ -1025,7 +1153,7 @@ if (end-of-file or data complete) { $txn->{result} = $txn->{buf}; - $txn->{finished}->broadcast; + $txn->{finished}->send; $txb->{cb}->($txn) of $txn->{cb}; # also call callback } @@ -1033,7 +1161,7 @@ request was already finished, it doesn't wait, of course, and returns the data: - $txn->{finished}->wait; + $txn->{finished}->recv; return $txn->{result}; The actual code goes further and collects all errors (Cs, exceptions) @@ -1078,10 +1206,10 @@ $fcp->txn_client_get ($url)->cb (sub { ... - $quit->broadcast; + $quit->send; }); - $quit->wait; + $quit->recv; =head1 BENCHMARKS @@ -1120,7 +1248,7 @@ I is the time, in microseconds, used to invoke a simple callback. The callback simply counts down a Perl variable and after it was -invoked "watcher" times, it would C<< ->broadcast >> a condvar once to +invoked "watcher" times, it would C<< ->send >> a condvar once to signal the end of this phase. I is the time, in microseconds, that it takes to destroy a single @@ -1376,19 +1504,31 @@ 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. +Utility functions: L. + +Event modules: L, L, L, L, L, +L, L, L, L, L. + +Implementations: L, L, +L, L, L, +L, L, +L. + +Non-blocking file handles, sockets, TCP clients and +servers: L, L. + +Asynchronous DNS: L. + +Coroutine support: L, L, L, L, -Nontrivial usage examples: L, L. +Nontrivial usage examples: L, L, L. =head1 AUTHOR