--- AnyEvent/lib/AnyEvent.pm 2009/07/28 13:08:17 1.262 +++ AnyEvent/lib/AnyEvent.pm 2010/02/15 18:02:35 1.312 @@ -183,6 +183,12 @@ =head2 I/O WATCHERS + $w = AnyEvent->io ( + fh => , + poll => <"r" or "w">, + cb => , + ); + You can create an I/O watcher by calling the C<< AnyEvent->io >> method with the following mandatory key-value pairs as arguments: @@ -221,6 +227,14 @@ =head2 TIME WATCHERS + $w = AnyEvent->timer (after => , cb => ); + + $w = AnyEvent->timer ( + after => , + interval => , + cb => , + ); + You can create a time watcher by calling the C<< AnyEvent->timer >> method with the following mandatory arguments: @@ -351,12 +365,21 @@ When this is the case, you can call this method, which will update the event loop's idea of "current time". +A typical example would be a script in a web server (e.g. C) - +when mod_perl executes the script, then the event loop will have the wrong +idea about the "current time" (being potentially far in the past, when the +script ran the last time). In that case you should arrange a call to C<< +AnyEvent->now_update >> each time the web server process wakes up again +(e.g. at the start of your script, or in a handler). + Note that updating the time I cause some events to be handled. =back =head2 SIGNAL WATCHERS + $w = AnyEvent->signal (signal => , cb => ); + You can watch for signals using a signal watcher, C is the signal I in uppercase and without any C prefix, C is the Perl callback to be invoked whenever a signal occurs. @@ -382,24 +405,47 @@ my $w = AnyEvent->signal (signal => "INT", cb => sub { exit 1 }); +=head3 Restart Behaviour + +While restart behaviour is up to the event loop implementation, most will +not restart syscalls (that includes L and AnyEvent's +pure perl implementation). + +=head3 Safe/Unsafe Signals + +Perl signals can be either "safe" (synchronous to opcode handling) or +"unsafe" (asynchronous) - the former might get delayed indefinitely, the +latter might corrupt your memory. + +AnyEvent signal handlers are, in addition, synchronous to the event loop, +i.e. they will not interrupt your running perl program but will only be +called as part of the normal event handling (just like timer, I/O etc. +callbacks, too). + =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 -seconds). This variable can be changed only before the first signal -watcher is created, and should be left alone otherwise. Higher values +callbacks to signals in a generic way, which is a pity, as you cannot +do race-free signal handling in perl, requiring C libraries for +this. AnyEvent will try to do it's best, which means 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 seconds). This +variable can be changed only before the first signal watcher is created, +and should be left alone otherwise. This variable determines how often +AnyEvent polls for signals (in case a wake-up was missed). 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. 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. +saving. + +All these problems can be avoided by installing the optional +L module, which works with most event loops. It 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). For those, you just have to suffer the delays. =head2 CHILD PROCESS WATCHERS + $w = AnyEvent->child (pid => , cb => ); + You can also watch on a child process exit and catch its exit status. The child process is specified by the C argument (one some backends, @@ -457,16 +503,21 @@ =head2 IDLE WATCHERS -Sometimes there is a need to do something, but it is not so important -to do it instantly, but only when there is nothing better to do. This -"nothing better to do" is usually defined to be "no other events need -attention by the event loop". - -Idle watchers ideally get invoked when the event loop has nothing -better to do, just before it would block the process to wait for new -events. Instead of blocking, the idle watcher is invoked. + $w = AnyEvent->idle (cb => ); + +Repeatedly invoke the callback after the process becomes idle, until +either the watcher is destroyed or new events have been detected. -Most event loops unfortunately do not really support idle watchers (only +Idle watchers are useful when there is a need to do something, but it +is not so important (or wise) to do it instantly. The callback will be +invoked only when there is "nothing better to do", which is usually +defined as "all outstanding events have been handled and no new events +have been detected". That means that idle watchers ideally get invoked +when the event loop has just polled for new events but none have been +detected. Instead of blocking to wait for more events, the idle watchers +will be invoked. + +Unfortunately, most event loops do not really support idle watchers (only EV, Event and Glib do it in a usable fashion) - for the rest, AnyEvent will simply call the callback "from time to time". @@ -492,6 +543,11 @@ =head2 CONDITION VARIABLES + $cv = AnyEvent->condvar; + + $cv->send (); + my @res = $cv->recv; + If you are familiar with some event loops you will know that all of them require you to run some blocking "loop", "run" or similar function that will actively watch for new events and call your callbacks. @@ -565,7 +621,7 @@ ); # this "blocks" (while handling events) till the callback - # calls -send $result_ready->recv; Example: wait for a timer, but take advantage of the fact that condition @@ -639,9 +695,10 @@ 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<< ->send >>, but that is not required. If no -callback was set, C will be called without any arguments. +>>, the (last) callback passed to C will be executed, passing the +condvar as first argument. That callback is I to call C<< ->send +>>, but that is not required. If no group callback was set, C will +be called without any arguments. You can think of C<< $cv->send >> giving you an OR condition (one call sends), while C<< $cv->begin >> and C<< $cv->end >> giving you an AND @@ -678,7 +735,7 @@ my $cv = AnyEvent->condvar; my %result; - $cv->begin (sub { $cv->send (\%result) }); + $cv->begin (sub { shift->send (\%result) }); for my $host (@list_of_hosts) { $cv->begin; @@ -763,10 +820,10 @@ 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, with the only argument being the condition -variable itself. Calling C inside the callback or at any later time -is guaranteed not to block. +The callback will be called when the condition becomes (or already was) +"true", i.e. when C or C are called (or were called), with +the only argument being the condition variable itself. Calling C +inside the callback or at any later time is guaranteed not to block. =back @@ -779,12 +836,11 @@ =item Backends that are autoprobed when no other event loop can be found. EV is the preferred backend when no other event loop seems to be in -use. If EV is not installed, then AnyEvent will try Event, and, failing -that, will fall back to its own pure-perl implementation, which is -available everywhere as it comes with AnyEvent itself. +use. If EV is not installed, then AnyEvent will fall back to its own +pure-perl implementation, which is available everywhere as it comes with +AnyEvent itself. AnyEvent::Impl::EV based on EV (interface to libev, best choice). - AnyEvent::Impl::Event based on Event, very stable, few glitches. AnyEvent::Impl::Perl pure-perl implementation, fast and portable. =item Backends that are transparently being picked up when they are used. @@ -795,6 +851,7 @@ when the main program loads an event module before anything starts to create watchers. Nothing special needs to be done by the main program. + AnyEvent::Impl::Event based on Event, very stable, few glitches. AnyEvent::Impl::Glib based on Glib, slow but very stable. AnyEvent::Impl::Tk based on Tk, very broken. AnyEvent::Impl::EventLib based on Event::Lib, leaks memory and worse. @@ -914,13 +971,26 @@ array will be ignored. Best use C when your application allows -it,as it takes care of these details. +it, as it takes care of these details. This variable is mainly useful for modules that can do something useful when AnyEvent is used and thus want to know when it is initialised, but do not need to even load it by default. This array provides the means to hook into AnyEvent passively, without loading it. +Example: To load Coro::AnyEvent whenever Coro and AnyEvent are used +together, you could put this into Coro (this is the actual code used by +Coro to accomplish this): + + if (defined $AnyEvent::MODEL) { + # AnyEvent already initialised, so load Coro::AnyEvent + require Coro::AnyEvent; + } else { + # AnyEvent not yet initialised, so make sure to load Coro::AnyEvent + # as soon as it is + push @AnyEvent::post_detect, sub { require Coro::AnyEvent }; + } + =back =head1 WHAT TO DO IN A MODULE @@ -1078,9 +1148,9 @@ # basically a tuned-down version of common::sense sub common_sense { - # no warnings - ${^WARNING_BITS} ^= ${^WARNING_BITS}; - # use strict vars subs + # from common:.sense 1.0 + ${^WARNING_BITS} = "\xfc\x3f\x33\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x00"; + # use strict vars subs - NO UTF-8, as Util.pm doesn't like this atm. (uts46data.pl) $^H |= 0x00000600; } @@ -1088,7 +1158,7 @@ use Carp (); -our $VERSION = 4.881; +our $VERSION = '5.24'; our $MODEL; our $AUTOLOAD; @@ -1096,13 +1166,12 @@ our @REGISTRY; -our $WIN32; - our $VERBOSE; BEGIN { - eval "sub WIN32(){ " . (($^O =~ /mswin32/i)*1) ." }"; - eval "sub TAINT(){ " . (${^TAINT}*1) . " }"; + eval "sub CYGWIN(){" . (($^O =~ /cygwin/i) *1) . "}"; + eval "sub WIN32 (){" . (($^O =~ /mswin32/i)*1) . "}"; + eval "sub TAINT (){" . (${^TAINT} *1) . "}"; delete @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} if ${^TAINT}; @@ -1124,11 +1193,11 @@ my @models = ( [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 + [Event:: => AnyEvent::Impl::Event::, 1], [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 @@ -1141,9 +1210,10 @@ # byzantine signal and broken child handling, among others. # IO::Async is rather hard to detect, as it doesn't have any # obvious default class. -# [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 + [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 + [AnyEvent::Impl::IOAsync:: => AnyEvent::Impl::IOAsync::], # requires special main program ); our %method = map +($_ => 1), @@ -1172,61 +1242,64 @@ } sub detect() { - unless ($MODEL) { - local $SIG{__DIE__}; + # free some memory + *detect = sub () { $MODEL }; - if ($ENV{PERL_ANYEVENT_MODEL} =~ /^([a-zA-Z]+)$/) { - my $model = "AnyEvent::Impl::$1"; - if (eval "require $model") { - $MODEL = $model; - warn "AnyEvent: loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it.\n" if $VERBOSE >= 2; - } else { - warn "AnyEvent: unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@" if $VERBOSE; + local $!; # for good measure + local $SIG{__DIE__}; + + if ($ENV{PERL_ANYEVENT_MODEL} =~ /^([a-zA-Z]+)$/) { + my $model = "AnyEvent::Impl::$1"; + if (eval "require $model") { + $MODEL = $model; + warn "AnyEvent: loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it.\n" if $VERBOSE >= 2; + } else { + warn "AnyEvent: unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@" if $VERBOSE; + } + } + + # check for already loaded models + unless ($MODEL) { + for (@REGISTRY, @models) { + my ($package, $model) = @$_; + if (${"$package\::VERSION"} > 0) { + if (eval "require $model") { + $MODEL = $model; + warn "AnyEvent: autodetected model '$model', using it.\n" if $VERBOSE >= 2; + last; + } } } - # check for already loaded models unless ($MODEL) { + # try to autoload a model for (@REGISTRY, @models) { - my ($package, $model) = @$_; - if (${"$package\::VERSION"} > 0) { - if (eval "require $model") { - $MODEL = $model; - warn "AnyEvent: autodetected model '$model', using it.\n" if $VERBOSE >= 2; - last; - } + my ($package, $model, $autoload) = @$_; + if ( + $autoload + and eval "require $package" + and ${"$package\::VERSION"} > 0 + and eval "require $model" + ) { + $MODEL = $model; + warn "AnyEvent: autoloaded model '$model', using it.\n" if $VERBOSE >= 2; + last; } } - unless ($MODEL) { - # try to autoload a model - for (@REGISTRY, @models) { - my ($package, $model, $autoload) = @$_; - if ( - $autoload - and eval "require $package" - and ${"$package\::VERSION"} > 0 - and eval "require $model" - ) { - $MODEL = $model; - warn "AnyEvent: autoloaded model '$model', using it.\n" if $VERBOSE >= 2; - last; - } - } - - $MODEL - or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: EV, Event or Glib.\n"; - } + $MODEL + or die "No event module selected for AnyEvent and autodetect failed. Install any one of these modules: EV, Event or Glib.\n"; } + } - push @{"$MODEL\::ISA"}, "AnyEvent::Base"; + @models = (); # free probe data - unshift @ISA, $MODEL; + push @{"$MODEL\::ISA"}, "AnyEvent::Base"; + unshift @ISA, $MODEL; - require AnyEvent::Strict if $ENV{PERL_ANYEVENT_STRICT}; + require AnyEvent::Strict if $ENV{PERL_ANYEVENT_STRICT}; - (shift @post_detect)->() while @post_detect; - } + (shift @post_detect)->() while @post_detect; $MODEL } @@ -1235,9 +1308,9 @@ (my $func = $AUTOLOAD) =~ s/.*://; $method{$func} - or Carp::croak "$func: not a valid method for AnyEvent objects"; + or Carp::croak "$func: not a valid AnyEvent class method"; - detect unless $MODEL; + detect; my $class = shift; $class->$func (@_); @@ -1260,20 +1333,73 @@ ($fh2, $rw) } +=head1 SIMPLIFIED AE API + +Starting with version 5.0, AnyEvent officially supports a second, much +simpler, API that is designed to reduce the calling, typing and memory +overhead. + +See the L manpage for details. + +=cut + +package AE; + +our $VERSION = $AnyEvent::VERSION; + +sub io($$$) { + AnyEvent->io (fh => $_[0], poll => $_[1] ? "w" : "r", cb => $_[2]) +} + +sub timer($$$) { + AnyEvent->timer (after => $_[0], interval => $_[1], cb => $_[2]) +} + +sub signal($$) { + AnyEvent->signal (signal => $_[0], cb => $_[1]) +} + +sub child($$) { + AnyEvent->child (pid => $_[0], cb => $_[1]) +} + +sub idle($) { + AnyEvent->idle (cb => $_[0]) +} + +sub cv(;&) { + AnyEvent->condvar (@_ ? (cb => $_[0]) : ()) +} + +sub now() { + AnyEvent->now +} + +sub now_update() { + AnyEvent->now_update +} + +sub time() { + AnyEvent->time +} + package AnyEvent::Base; # default implementations for many methods -sub _time { - # 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; - # 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 - } +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; + # 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 + } + }; + die if $@; &_time } @@ -1291,34 +1417,31 @@ # default implementation for ->signal our $HAVE_ASYNC_INTERRUPT; -our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); -our (%SIG_ASY, %SIG_ASY_W); -our ($SIG_COUNT, $SIG_TW); -sub _signal_exec { - $HAVE_ASYNC_INTERRUPT - ? $SIGPIPE_R->drain - : sysread $SIGPIPE_R, my $dummy, 9; +sub _have_async_interrupt() { + $HAVE_ASYNC_INTERRUPT = 1*(!$ENV{PERL_ANYEVENT_AVOID_ASYNC_INTERRUPT} + && eval "use Async::Interrupt 1.02 (); 1") + unless defined $HAVE_ASYNC_INTERRUPT; - while (%SIG_EV) { - for (keys %SIG_EV) { - delete $SIG_EV{$_}; - $_->() for values %{ $SIG_CB{$_} || {} }; - } - } + $HAVE_ASYNC_INTERRUPT } +our ($SIGPIPE_R, $SIGPIPE_W, %SIG_CB, %SIG_EV, $SIG_IO); +our (%SIG_ASY, %SIG_ASY_W); +our ($SIG_COUNT, $SIG_TW); + # install a dummy wakeup watcher to reduce signal catching latency +# used by Impls sub _sig_add() { unless ($SIG_COUNT++) { # try to align timer on a full-second boundary, if possible - my $NOW = AnyEvent->now; + my $NOW = AE::now; - $SIG_TW = AnyEvent->timer ( - after => $MAX_SIGNAL_LATENCY - ($NOW - int $NOW), - interval => $MAX_SIGNAL_LATENCY, - cb => sub { }, # just for the PERL_ASYNC_CHECK - ); + $SIG_TW = AE::timer + $MAX_SIGNAL_LATENCY - ($NOW - int $NOW), + $MAX_SIGNAL_LATENCY, + sub { } # just for the PERL_ASYNC_CHECK + ; } } @@ -1327,100 +1450,145 @@ unless --$SIG_COUNT; } -sub _signal { - my (undef, %arg) = @_; +our $_sig_name_init; $_sig_name_init = sub { + eval q{ # poor man's autoloading + undef $_sig_name_init; + + if (_have_async_interrupt) { + *sig2num = \&Async::Interrupt::sig2num; + *sig2name = \&Async::Interrupt::sig2name; + } else { + require Config; - my $signal = uc $arg{signal} - or Carp::croak "required option 'signal' is missing"; + my %signame2num; + @signame2num{ split ' ', $Config::Config{sig_name} } + = split ' ', $Config::Config{sig_num}; + + my @signum2name; + @signum2name[values %signame2num] = keys %signame2num; + + *sig2num = sub($) { + $_[0] > 0 ? shift : $signame2num{+shift} + }; + *sig2name = sub ($) { + $_[0] > 0 ? $signum2name[+shift] : shift + }; + } + }; + die if $@; +}; - if ($HAVE_ASYNC_INTERRUPT) { - # async::interrupt +sub sig2num ($) { &$_sig_name_init; &sig2num } +sub sig2name($) { &$_sig_name_init; &sig2name } - $signal = Async::Interrupt::sig2num ($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, - ; +sub signal { + eval q{ # poor man's autoloading {} + # probe for availability of Async::Interrupt + if (_have_async_interrupt) { + warn "AnyEvent: using Async::Interrupt for race-free signal handling.\n" if $VERBOSE >= 8; - } else { - # pure perl + $SIGPIPE_R = new Async::Interrupt::EventPipe; + $SIG_IO = AE::io $SIGPIPE_R->fileno, 0, \&_signal_exec; - # AE::Util has been loaded in signal - $signal = AnyEvent::Util::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}; - }; + } else { + warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8; - # can't do signal processing without introducing races in pure perl, - # so limit the signal latency. - _sig_add; - } + require Fcntl; - bless [$signal, $arg{cb}], "AnyEvent::Base::signal" -} + if (AnyEvent::WIN32) { + require AnyEvent::Util; -sub signal { - # probe for availability of Async::Interrupt - if (!$ENV{PERL_ANYEVENT_AVOID_ASYNC_INTERRUPT} && eval "use Async::Interrupt 1.0 (); 1") { - warn "AnyEvent: using Async::Interrupt for race-free signal handling.\n" if $VERBOSE >= 8; - - $HAVE_ASYNC_INTERRUPT = 1; - $SIGPIPE_R = new Async::Interrupt::EventPipe; - $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R->fileno, poll => "r", cb => \&_signal_exec); + ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe (); + AnyEvent::Util::fh_nonblocking ($SIGPIPE_R, 1) if $SIGPIPE_R; + 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 + + # 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; + } - } else { - warn "AnyEvent: using emulated perl signal handling with latency timer.\n" if $VERBOSE >= 8; + $SIGPIPE_R + or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n"; - require Fcntl; + $SIG_IO = AE::io $SIGPIPE_R, 0, \&_signal_exec; + } - if (AnyEvent::WIN32) { - require AnyEvent::Util; + *signal = sub { + my (undef, %arg) = @_; - ($SIGPIPE_R, $SIGPIPE_W) = AnyEvent::Util::portable_pipe (); - AnyEvent::Util::fh_nonblocking ($SIGPIPE_R) if $SIGPIPE_R; - AnyEvent::Util::fh_nonblocking ($SIGPIPE_W) 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 - - # 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; - } + my $signal = uc $arg{signal} + or Carp::croak "required option 'signal' is missing"; - $SIGPIPE_R - or Carp::croak "AnyEvent: unable to create a signal reporting pipe: $!\n"; + if ($HAVE_ASYNC_INTERRUPT) { + # async::interrupt - $SIG_IO = AnyEvent->io (fh => $SIGPIPE_R, poll => "r", cb => \&_signal_exec); - } + $signal = sig2num $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, + ; - *signal = \&_signal; - &signal -} + } 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; + } -sub AnyEvent::Base::signal::DESTROY { - my ($signal, $cb) = @{$_[0]}; + bless [$signal, $arg{cb}], "AnyEvent::Base::signal" + }; - _sig_del; + *AnyEvent::Base::signal::DESTROY = sub { + my ($signal, $cb) = @{$_[0]}; - delete $SIG_CB{$signal}{$cb}; + _sig_del; - $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} }; + delete $SIG_CB{$signal}{$cb}; + + $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} }; + }; + + *_signal_exec = sub { + $HAVE_ASYNC_INTERRUPT + ? $SIGPIPE_R->drain + : sysread $SIGPIPE_R, (my $dummy), 9; + + while (%SIG_EV) { + for (keys %SIG_EV) { + delete $SIG_EV{$_}; + $_->() for values %{ $SIG_CB{$_} || {} }; + } + } + }; + }; + die if $@; + + &signal } # default implementation for ->child @@ -1430,6 +1598,7 @@ our $CHLD_DELAY_W; our $WNOHANG; +# used by many Impl's sub _emit_childstatus($$) { my (undef, $rpid, $rstatus) = @_; @@ -1438,78 +1607,92 @@ values %{ $PID_CB{0} || {} }; } -sub _sigchld { - my $pid; +sub child { + eval q{ # poor man's autoloading {} + *_sigchld = sub { + my $pid; - AnyEvent->_emit_childstatus ($pid, $?) - while ($pid = waitpid -1, $WNOHANG) > 0; -} + AnyEvent->_emit_childstatus ($pid, $?) + while ($pid = waitpid -1, $WNOHANG) > 0; + }; -sub child { - my (undef, %arg) = @_; + *child = sub { + my (undef, %arg) = @_; - defined (my $pid = $arg{pid} + 0) - or Carp::croak "required option 'pid' is missing"; + defined (my $pid = $arg{pid} + 0) + or Carp::croak "required option 'pid' is missing"; - $PID_CB{$pid}{$arg{cb}} = $arg{cb}; + $PID_CB{$pid}{$arg{cb}} = $arg{cb}; - # WNOHANG is almost cetrainly 1 everywhere - $WNOHANG ||= $^O =~ /^(?:openbsd|netbsd|linux|freebsd|cygwin|MSWin32)$/ - ? 1 - : eval { local $SIG{__DIE__}; 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; - } + # WNOHANG is almost cetrainly 1 everywhere + $WNOHANG ||= $^O =~ /^(?:openbsd|netbsd|linux|freebsd|cygwin|MSWin32)$/ + ? 1 + : eval { local $SIG{__DIE__}; require POSIX; &POSIX::WNOHANG } || 1; + + unless ($CHLD_W) { + $CHLD_W = AE::signal CHLD => \&_sigchld; + # child could be a zombie already, so make at least one round + &_sigchld; + } - bless [$pid, $arg{cb}], "AnyEvent::Base::child" -} + bless [$pid, $arg{cb}], "AnyEvent::Base::child" + }; + + *AnyEvent::Base::child::DESTROY = sub { + my ($pid, $cb) = @{$_[0]}; -sub AnyEvent::Base::child::DESTROY { - my ($pid, $cb) = @{$_[0]}; + delete $PID_CB{$pid}{$cb}; + delete $PID_CB{$pid} unless keys %{ $PID_CB{$pid} }; - delete $PID_CB{$pid}{$cb}; - delete $PID_CB{$pid} unless keys %{ $PID_CB{$pid} }; + undef $CHLD_W unless keys %PID_CB; + }; + }; + die if $@; - undef $CHLD_W unless keys %PID_CB; + &child } # idle emulation is done by simply using a timer, regardless # of whether the process is idle or not, and not letting # the callback use more than 50% of the time. sub idle { - my (undef, %arg) = @_; + eval q{ # poor man's autoloading {} + *idle = sub { + my (undef, %arg) = @_; + + my ($cb, $w, $rcb) = $arg{cb}; + + $rcb = sub { + if ($cb) { + $w = _time; + &$cb; + $w = _time - $w; + + # never use more then 50% of the time for the idle watcher, + # within some limits + $w = 0.0001 if $w < 0.0001; + $w = 5 if $w > 5; + + $w = AE::timer $w, 0, $rcb; + } else { + # clean up... + undef $w; + undef $rcb; + } + }; - my ($cb, $w, $rcb) = $arg{cb}; + $w = AE::timer 0.05, 0, $rcb; - $rcb = sub { - if ($cb) { - $w = _time; - &$cb; - $w = _time - $w; - - # never use more then 50% of the time for the idle watcher, - # within some limits - $w = 0.0001 if $w < 0.0001; - $w = 5 if $w > 5; + bless \\$cb, "AnyEvent::Base::idle" + }; - $w = AnyEvent->timer (after => $w, cb => $rcb); - } else { - # clean up... - undef $w; - undef $rcb; - } + *AnyEvent::Base::idle::DESTROY = sub { + undef $${$_[0]}; + }; }; + die if $@; - $w = AnyEvent->timer (after => 0.05, cb => $rcb); - - bless \\$cb, "AnyEvent::Base::idle" -} - -sub AnyEvent::Base::idle::DESTROY { - undef $${$_[0]}; + &idle } package AnyEvent::CondVar; @@ -1567,8 +1750,14 @@ } sub cb { - $_[0]{_ae_cb} = $_[1] if @_ > 1; - $_[0]{_ae_cb} + my $cv = shift; + + @_ + and $cv->{_ae_cb} = shift + and $cv->{_ae_sent} + and (delete $cv->{_ae_cb})->($cv); + + $cv->{_ae_cb} } sub begin { @@ -1787,16 +1976,9 @@ }, ); - my $time_watcher; # can only be used once - - sub new_timer { - $timer = AnyEvent->timer (after => 1, cb => sub { - warn "timeout\n"; # print 'timeout' about every second - &new_timer; # and restart the time - }); - } - - new_timer; # create first timer + my $time_watcher = AnyEvent->timer (after => 1, interval => 1, cb => sub { + warn "timeout\n"; # print 'timeout' at most every second + }); $cv->recv; # wait until user enters /^q/i @@ -1937,7 +2119,8 @@ which it is), lets them fire exactly once and destroys them again. Source code for this benchmark is found as F in the AnyEvent -distribution. +distribution. It uses the L interface, which makes a real difference +for the EV and Perl backends only. =head3 Explanation of the columns @@ -1968,18 +2151,18 @@ =head3 Results name watchers bytes create invoke destroy comment - EV/EV 400000 224 0.47 0.35 0.27 EV native interface - EV/Any 100000 224 2.88 0.34 0.27 EV + AnyEvent watchers - CoroEV/Any 100000 224 2.85 0.35 0.28 coroutines + Coro::Signal - Perl/Any 100000 452 4.13 0.73 0.95 pure perl implementation - Event/Event 16000 517 32.20 31.80 0.81 Event native interface - Event/Any 16000 590 35.85 31.55 1.06 Event + AnyEvent watchers - IOAsync/Any 16000 989 38.10 32.77 11.13 via IO::Async::Loop::IO_Poll - IOAsync/Any 16000 990 37.59 29.50 10.61 via IO::Async::Loop::Epoll - Glib/Any 16000 1357 102.33 12.31 51.00 quadratic behaviour - Tk/Any 2000 1860 27.20 66.31 14.00 SEGV with >> 2000 watchers - POE/Event 2000 6328 109.99 751.67 14.02 via POE::Loop::Event - POE/Select 2000 6027 94.54 809.13 579.80 via POE::Loop::Select + EV/EV 100000 223 0.47 0.43 0.27 EV native interface + EV/Any 100000 223 0.48 0.42 0.26 EV + AnyEvent watchers + Coro::EV/Any 100000 223 0.47 0.42 0.26 coroutines + Coro::Signal + Perl/Any 100000 431 2.70 0.74 0.92 pure perl implementation + Event/Event 16000 516 31.16 31.84 0.82 Event native interface + Event/Any 16000 1203 42.61 34.79 1.80 Event + AnyEvent watchers + IOAsync/Any 16000 1911 41.92 27.45 16.81 via IO::Async::Loop::IO_Poll + IOAsync/Any 16000 1726 40.69 26.37 15.25 via IO::Async::Loop::Epoll + Glib/Any 16000 1118 89.00 12.57 51.17 quadratic behaviour + Tk/Any 2000 1346 20.96 10.75 8.00 SEGV with >> 2000 watchers + POE/Any 2000 6951 108.97 795.32 14.24 via POE::Loop::Event + POE/Any 2000 6648 94.79 774.40 575.51 via POE::Loop::Select =head3 Discussion @@ -2001,9 +2184,10 @@ cycles with POE. C is the sole leader regarding speed and memory use, which are both -maximal/minimal, respectively. Even when going through AnyEvent, it uses -far less memory than any other event loop and is still faster than Event -natively. +maximal/minimal, respectively. When using the L API there is zero +overhead (when going through the AnyEvent API create is about 5-6 times +slower, with other times being equal, so still uses far less memory than +any other event loop and is still faster than Event natively). The pure perl implementation is hit in a few sweet spots (both the constant timeout and the use of a single fd hit optimisations in the perl @@ -2087,7 +2271,8 @@ connections, most of which are idle at any one point in time. Source code for this benchmark is found as F in the AnyEvent -distribution. +distribution. It uses the L interface, which makes a real difference +for the EV and Perl backends only. =head3 Explanation of the columns @@ -2105,13 +2290,13 @@ =head3 Results name sockets create request - EV 20000 69.01 11.16 - Perl 20000 73.32 35.87 - IOAsync 20000 157.00 98.14 epoll - IOAsync 20000 159.31 616.06 poll - Event 20000 212.62 257.32 - Glib 20000 651.16 1896.30 - POE 20000 349.67 12317.24 uses POE::Loop::Event + EV 20000 62.66 7.99 + Perl 20000 68.32 32.64 + IOAsync 20000 174.06 101.15 epoll + IOAsync 20000 174.67 610.84 poll + Event 20000 202.69 242.91 + Glib 20000 557.01 1689.52 + POE 20000 341.54 12086.32 uses POE::Loop::Event =head3 Discussion @@ -2247,13 +2432,13 @@ backend easily beats IO::Lambda and POE. And even the 100% non-blocking version written using the high-level (and -slow :) L abstraction beats both POE and IO::Lambda by a -large margin, even though it does all of DNS, tcp-connect and socket I/O -in a non-blocking way. +slow :) L abstraction beats both POE and IO::Lambda +higher level ("unoptimised") abstractions by a large margin, even though +it does all of DNS, tcp-connect and socket I/O in a non-blocking way. The two AnyEvent benchmarks programs can be found as F and F in the AnyEvent distribution, the remaining benchmarks are -part of the IO::lambda distribution and were used without any changes. +part of the IO::Lambda distribution and were used without any changes. =head1 SIGNALS @@ -2305,8 +2490,8 @@ That does not mean that AnyEvent won't take advantage of some additional modules if they are installed. -This section epxlains which additional modules will be used, and how they -affect AnyEvent's operetion. +This section explains which additional modules will be used, and how they +affect AnyEvent's operation. =over 4 @@ -2321,7 +2506,7 @@ If this module is available, then it will be used to implement signal catching, which means that signals will not be delayed, and the event loop -will not be interrupted regularly, which is more efficient (And good for +will not be interrupted regularly, which is more efficient (and good for battery life on laptops). This affects not just the pure-perl event loop, but also other event loops @@ -2352,8 +2537,8 @@ =item L and L -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 +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 advantage of the ultra-high-speed L module when it is installed. In fact, L will use L by default if it is @@ -2378,13 +2563,31 @@ =head1 FORK Most event libraries are not fork-safe. The ones who are usually are -because they rely on inefficient but fork-safe C or C calls +- higher performance APIs such as BSD's kqueue or the dreaded Linux epoll +are usually badly thought-out hacks that are incompatible with fork in +one way or another. Only L is fully fork-aware and ensures that you +continue event-processing in both parent and child (or both, if you know +what you are doing). + +This means that, in general, you cannot fork and do event processing in +the child if the event library was initialised before the fork (which +usually happens when the first AnyEvent watcher is created, or the library +is loaded). If you have to fork, you must either do so I creating your first watcher OR you must not use AnyEvent at all in the child OR you must do something completely out of the scope of AnyEvent. +The problem of doing event processing in the parent I the child +is much more complicated: even for backends that I fork-aware or +fork-safe, their behaviour is not usually what you want: fork clones all +watchers, that means all timers, I/O watchers etc. are active in both +parent and child, which is almost never what you want. USing C +to start worker children from some kind of manage rprocess is usually +preferred, because it is much easier and cleaner, at the expense of having +to have another binary. + =head1 SECURITY CONSIDERATIONS