--- AnyEvent/lib/AnyEvent.pm 2011/09/01 04:07:18 1.380 +++ AnyEvent/lib/AnyEvent.pm 2011/10/01 22:39:29 1.387 @@ -417,9 +417,9 @@ =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. +Perl signals can be either "safe" (synchronous to opcode handling) +or "unsafe" (asynchronous) - the former might delay signal delivery +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 @@ -428,23 +428,21 @@ =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, requiring C libraries for -this. AnyEvent will try to do its 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. +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, requiring +C libraries for this. AnyEvent will try to do its best, which +means in some cases, signals will be delayed. The maximum time +a signal might be delayed is 10 seconds by default, but can +be overriden via C<$ENV{PERL_ANYEVENT_MAX_SIGNAL_LATENCY}> or +C<$AnyEvent::MAX_SIGNAL_LATENCY> - see the Ö +section for details. 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 its own workaround with -one-second latency). For those, you just have to suffer the delays. +(and not with L currently). For those, you just have to suffer the +delays. =head2 CHILD PROCESS WATCHERS @@ -1239,12 +1237,11 @@ our $VERSION = '6.02'; our $MODEL; - our @ISA; - our @REGISTRY; - our $VERBOSE; +our %PROTOCOL; # (ipv4|ipv6) => (1|2), higher numbers are preferred +our $MAX_SIGNAL_LATENCY = $ENV{PERL_ANYEVENT_MAX_SIGNAL_LATENCY} || 10; # executes after the BEGIN block below (tainting!) BEGIN { require "AnyEvent/constants.pl"; @@ -1260,14 +1257,10 @@ @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} = () if ${^TAINT}; - $VERBOSE = length $ENV{PERL_ANYEVENT_VERBOSE} ? $ENV{PERL_ANYEVENT_VERBOSE}*1 : 3; -} - -our $MAX_SIGNAL_LATENCY = 10; + # $ENV{PERL_ANYEVENT_xxx} now valid -our %PROTOCOL; # (ipv4|ipv6) => (1|2), higher numbers are preferred + $VERBOSE = length $ENV{PERL_ANYEVENT_VERBOSE} ? $ENV{PERL_ANYEVENT_VERBOSE}*1 : 4; -{ my $idx; $PROTOCOL{$_} = ++$idx for reverse split /\s*,\s*/, @@ -1310,8 +1303,8 @@ sub log($$;@) { # only load the big bloated module when we actually are about to log something - if ($_[0] <= $VERBOSE) { # also catches non-numeric levels(!) - require AnyEvent::Log; + if ($_[0] <= ($VERBOSE || 1)) { # also catches non-numeric levels(!) and fatal + require AnyEvent::Log; # among other things, sets $VERBOSE to 9 # AnyEvent::Log overwrites this function goto &log; } @@ -1319,20 +1312,51 @@ 0 # not logged } +sub logger($;$) { + package AnyEvent::Log; + + my ($level, $renabled) = @_; + + $$renabled = $level <= $VERBOSE; + + my $pkg = (caller)[0]; + + my $logger = [$pkg, $level, $renabled]; + + our %LOGGER; + $LOGGER{$logger+0} = $logger; + + require AnyEvent::Util; + my $guard = AnyEvent::Util::guard (sub { + # "clean up" + delete $LOGGER{$logger+0}; + }); + + sub { + return 0 unless $$renabled; + + $guard if 0; # keep guard alive, but don't cause runtime overhead + require AnyEvent::Log unless $AnyEvent::Log::VERSION; + package AnyEvent::Log; + _log ($logger->[0], $level, @_) # logger->[0] has been converted at load time + } +} + if (length $ENV{PERL_ANYEVENT_LOG}) { require AnyEvent::Log; # AnyEvent::Log does the thing for us } our @models = ( - [EV:: => AnyEvent::Impl::EV:: , 1], - [AnyEvent::Loop:: => AnyEvent::Impl::Perl:: , 1], + [EV:: => AnyEvent::Impl::EV::], + [AnyEvent::Loop:: => AnyEvent::Impl::Perl::], # everything below here will not (normally) be autoprobed # as the pure perl backend should work everywhere # and is usually faster - [Event:: => AnyEvent::Impl::Event::, 1], - [Glib:: => AnyEvent::Impl::Glib:: , 1], # becomes extremely slow with many watchers + [Irssi:: => AnyEvent::Impl::Irssi::], # Irssi has a bogus "Event" package, so msut be near the top + [Event:: => AnyEvent::Impl::Event::], # slow, stable + [Glib:: => AnyEvent::Impl::Glib::], # becomes extremely slow with many watchers + # everything below here should not be autoloaded [Event::Lib:: => AnyEvent::Impl::EventLib::], # too buggy - [Irssi:: => AnyEvent::Impl::Irssi::], # Irssi has a bogus "Event" package [Tk:: => AnyEvent::Impl::Tk::], # crashes with many handles [Qt:: => AnyEvent::Impl::Qt::], # requires special main program [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza @@ -1371,6 +1395,14 @@ sub detect() { return $MODEL if $MODEL; # some programs keep references to detect + # IO::Async::Loop::AnyEvent is extremely evil, refuse to work with it + # the author knows about the problems and what it does to AnyEvent as a whole + # (and the ability of others to use AnyEvent), but simply wants to abuse AnyEvent + # anyway. + AnyEvent::log fatal => "AnyEvent: IO::Async::Loop::AnyEvent detected - this module is broken by design,\n" + . "abuses internals and breaks AnyEvent, will not continue." + if exists $INC{"IO/Async/Loop/AnyEvent.pm"}; + local $!; # for good measure local $SIG{__DIE__}; # we use eval @@ -1391,7 +1423,7 @@ AnyEvent::log 7 => "loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it."; $MODEL = $model; } else { - AnyEvent::log 5 => "unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@"; + AnyEvent::log 4 => "unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@"; } } @@ -1411,10 +1443,9 @@ unless ($MODEL) { # try to autoload a model for (@REGISTRY, @models) { - my ($package, $model, $autoload) = @$_; + my ($package, $model) = @$_; if ( - $autoload - and eval "require $package" + eval "require $package" and ${"$package\::VERSION"} > 0 and eval "require $model" ) { @@ -1425,7 +1456,7 @@ } $MODEL - or die "AnyEvent: backend autodetection failed - did you properly install AnyEvent?"; + or AnyEvent::log fatal => "AnyEvent: backend autodetection failed - did you properly install AnyEvent?"; } } @@ -2102,10 +2133,10 @@ =item C -If this env variable is set, then its contents will be interpreted by -C (after replacing every occurance of -C<$$> by the process pid) and an C is bound on -that port. The shell object is saved in C<$AnyEvent::Debug::SHELL>. +If this env variable is nonempty, then its contents will be interpreted by +C and C (after +replacing every occurance of C<$$> by the process pid). The shell object +is saved in C<$AnyEvent::Debug::SHELL>. This happens when the first watcher is created. @@ -2113,9 +2144,15 @@ F<< /tmp/debug.sock >>, you could use this: PERL_ANYEVENT_DEBUG_SHELL=/tmp/debug\$\$.sock perlprog + # connect with e.g.: socat readline /tmp/debug123.sock -Note that creating sockets in F is very unsafe on multiuser -systems. +Or to bind to tcp port 4545 on localhost: + + PERL_ANYEVENT_DEBUG_SHELL=127.0.0.1:4545 perlprog + # connect with e.g.: telnet localhost 4545 + +Note that creating sockets in F or on localhost is very unsafe on +multiuser systems. =item C @@ -2190,6 +2227,28 @@ resolver - this is the maximum number of parallel DNS requests that are sent to the DNS server. +=item C + +Perl has inherently racy signal handling (you can basically choose between +losing signals and memory corruption) - pure perl event loops (including +C, when C isn't available) therefore +have to poll regularly to avoid losing signals. + +Some event loops are racy, but don't poll regularly, and some event loops +are written in C but are still racy. For those event loops, AnyEvent +installs a timer that regularly wakes up the event loop. + +By default, the interval for this timer is C<10> seconds, but you can +override this delay with this environment variable (or by setting +the C<$AnyEvent::MAX_SIGNAL_LATENCY> variable before creating signal +watchers). + +Lower values increase CPU (and energy) usage, higher values can introduce +long delays when reaping children or waiting for signals. + +The L module, if available, will be used to avoid this +polling (with most event loops). + =item C The absolute path to a F-style file to use instead of