--- AnyEvent/lib/AnyEvent.pm 2010/02/15 18:02:35 1.312 +++ AnyEvent/lib/AnyEvent.pm 2010/04/12 02:50:31 1.320 @@ -9,7 +9,10 @@ use AnyEvent; - # file descriptor readable + # if you prefer function calls, look at the L manpage for + # an alternative API. + + # file handle or descriptor readable my $w = AnyEvent->io (fh => $fh, poll => "r", cb => sub { ... }); # one-shot or repeating timers @@ -608,21 +611,21 @@ Example: wait for a timer. - # wait till the result is ready - my $result_ready = AnyEvent->condvar; + # condition: "wait till the timer is fired" + my $timer_fired = AnyEvent->condvar; - # do something such as adding a timer - # or socket watcher the calls $result_ready->send - # when the "result" is ready. + # create the timer - we could wait for, say + # a handle becomign ready, or even an + # AnyEvent::HTTP request to finish, but # in this case, we simply use a timer: my $w = AnyEvent->timer ( after => 1, - cb => sub { $result_ready->send }, + cb => sub { $timer_fired->send }, ); # this "blocks" (while handling events) till the callback # calls ->send - $result_ready->recv; + $timer_fired->recv; Example: wait for a timer, but take advantage of the fact that condition variables are also callable directly. @@ -1158,7 +1161,7 @@ use Carp (); -our $VERSION = '5.24'; +our $VERSION = '5.26'; our $MODEL; our $AUTOLOAD; @@ -1169,9 +1172,9 @@ our $VERBOSE; BEGIN { - eval "sub CYGWIN(){" . (($^O =~ /cygwin/i) *1) . "}"; - eval "sub WIN32 (){" . (($^O =~ /mswin32/i)*1) . "}"; - eval "sub TAINT (){" . (${^TAINT} *1) . "}"; + require "AnyEvent/constants.pl"; + + eval "sub TAINT (){" . (${^TAINT}*1) . "}"; delete @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} if ${^TAINT}; @@ -1224,17 +1227,11 @@ sub post_detect(&) { my ($cb) = @_; - if ($MODEL) { - $cb->(); - - undef - } else { - push @post_detect, $cb; + push @post_detect, $cb; - defined wantarray - ? bless \$cb, "AnyEvent::Util::postdetect" - : () - } + defined wantarray + ? bless \$cb, "AnyEvent::Util::postdetect" + : () } sub AnyEvent::Util::postdetect::DESTROY { @@ -1297,10 +1294,23 @@ push @{"$MODEL\::ISA"}, "AnyEvent::Base"; unshift @ISA, $MODEL; + # now nuke some methods that are overriden by the backend. + # SUPER is not allowed. + for (qw(time signal child idle)) { + undef &{"AnyEvent::Base::$_"} + if defined &{"$MODEL\::$_"}; + } + require AnyEvent::Strict if $ENV{PERL_ANYEVENT_STRICT}; (shift @post_detect)->() while @post_detect; + *post_detect = sub(&) { + shift->(); + + undef + }; + $MODEL } @@ -1337,7 +1347,7 @@ Starting with version 5.0, AnyEvent officially supports a second, much simpler, API that is designed to reduce the calling, typing and memory -overhead. +overhead by using function call syntax and a fixed number of parameters. See the L manpage for details. @@ -1347,6 +1357,9 @@ our $VERSION = $AnyEvent::VERSION; +# fall back to the main API by default - backends and AnyEvent::Base +# implementations can overwrite these. + sub io($$$) { AnyEvent->io (fh => $_[0], poll => $_[1] ? "w" : "r", cb => $_[2]) } @@ -1387,31 +1400,44 @@ # default implementations for many methods -sub _time() { - eval q{ # poor man's autoloading +sub time { + eval q{ # poor man's autoloading {} # probe for availability of Time::HiRes if (eval "use Time::HiRes (); Time::HiRes::time (); 1") { warn "AnyEvent: using Time::HiRes for sub-second timing accuracy.\n" if $VERBOSE >= 8; - *_time = \&Time::HiRes::time; + *AE::time = \&Time::HiRes::time; # if (eval "use POSIX (); (POSIX::times())... } else { warn "AnyEvent: using built-in time(), WARNING, no sub-second resolution!\n" if $VERBOSE; - *_time = sub (){ time }; # epic fail + *AE::time = sub (){ time }; # epic fail } + + *time = sub { AE::time }; # different prototypes }; die if $@; - &_time + &time } -sub time { _time } -sub now { _time } +*now = \&time; + sub now_update { } # default implementation for ->condvar sub condvar { - bless { @_ == 3 ? (_ae_cb => $_[2]) : () }, "AnyEvent::CondVar" + eval q{ # poor man's autoloading {} + *condvar = sub { + bless { @_ == 3 ? (_ae_cb => $_[2]) : () }, "AnyEvent::CondVar" + }; + + *AE::cv = sub (;&) { + bless { @_ ? (_ae_cb => shift) : () }, "AnyEvent::CondVar" + }; + }; + die if $@; + + &condvar } # default implementation for ->signal @@ -1451,7 +1477,7 @@ } our $_sig_name_init; $_sig_name_init = sub { - eval q{ # poor man's autoloading + eval q{ # poor man's autoloading {} undef $_sig_name_init; if (_have_async_interrupt) { @@ -1493,8 +1519,6 @@ } else { warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8; - require Fcntl; - if (AnyEvent::WIN32) { require AnyEvent::Util; @@ -1503,12 +1527,12 @@ AnyEvent::Util::fh_nonblocking ($SIGPIPE_W, 1) 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 + fcntl $SIGPIPE_R, AnyEvent::F_SETFL, AnyEvent::O_NONBLOCK if $SIGPIPE_R; + fcntl $SIGPIPE_W, AnyEvent::F_SETFL, AnyEvent::O_NONBLOCK if $SIGPIPE_W; # just in case # 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; + fcntl $SIGPIPE_R, AnyEvent::F_SETFD, AnyEvent::FD_CLOEXEC; + fcntl $SIGPIPE_W, AnyEvent::F_SETFD, AnyEvent::FD_CLOEXEC; } $SIGPIPE_R @@ -1517,45 +1541,43 @@ $SIG_IO = AE::io $SIGPIPE_R, 0, \&_signal_exec; } - *signal = sub { - my (undef, %arg) = @_; - - my $signal = uc $arg{signal} - or Carp::croak "required option 'signal' is missing"; - - if ($HAVE_ASYNC_INTERRUPT) { - # async::interrupt - - $signal = sig2num $signal; - $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; + *signal = $HAVE_ASYNC_INTERRUPT + ? sub { + my (undef, %arg) = @_; + + # async::interrupt + my $signal = sig2num $arg{signal}; + $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; + + $SIG_ASY{$signal} ||= new Async::Interrupt + cb => sub { undef $SIG_EV{$signal} }, + signal => $signal, + pipe => [$SIGPIPE_R->filenos], + pipe_autodrain => 0, + ; + + bless [$signal, $arg{cb}], "AnyEvent::Base::signal" + } + : sub { + my (undef, %arg) = @_; + + # pure perl + my $signal = sig2name $arg{signal}; + $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; + + $SIG{$signal} ||= sub { + local $!; + syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; + undef $SIG_EV{$signal}; + }; + + # can't do signal processing without introducing races in pure perl, + # so limit the signal latency. + _sig_add; - $SIG_ASY{$signal} ||= new Async::Interrupt - cb => sub { undef $SIG_EV{$signal} }, - signal => $signal, - pipe => [$SIGPIPE_R->filenos], - pipe_autodrain => 0, - ; - - } else { - # pure perl - - # AE::Util has been loaded in signal - $signal = sig2name $signal; - $SIG_CB{$signal}{$arg{cb}} = $arg{cb}; - - $SIG{$signal} ||= sub { - local $!; - syswrite $SIGPIPE_W, "\x00", 1 unless %SIG_EV; - undef $SIG_EV{$signal}; - }; - - # can't do signal processing without introducing races in pure perl, - # so limit the signal latency. - _sig_add; - } - - bless [$signal, $arg{cb}], "AnyEvent::Base::signal" - }; + bless [$signal, $arg{cb}], "AnyEvent::Base::signal" + } + ; *AnyEvent::Base::signal::DESTROY = sub { my ($signal, $cb) = @{$_[0]}; @@ -2061,7 +2083,7 @@ that occurred during request processing. The C method detects whether an exception as thrown (it is stored inside the $txn object) and just throws the exception, which means connection errors and other -problems get reported tot he code that tries to use the result, not in a +problems get reported to the code that tries to use the result, not in a random callback. All of this enables the following usage styles: @@ -2528,6 +2550,9 @@ C, and is the fastest backend I. You can even embed L/L in it (or vice versa, see L and L). +If you only use backends that rely on another event loop (e.g. C), +then this module will do nothing for you. + =item L The guard module, when used, will be used to implement @@ -2538,12 +2563,9 @@ =item L and L One of these modules is required when you want to read or write JSON data -via L. It is also written in pure-perl, but can take +via L. L is also written in pure-perl, but can take advantage of the ultra-high-speed L module when it is installed. -In fact, L will use L by default if it is -installed. - =item L Implementing TLS/SSL in Perl is certainly interesting, but not very