--- AnyEvent/lib/AnyEvent.pm 2011/08/17 02:30:38 1.368 +++ AnyEvent/lib/AnyEvent.pm 2011/09/01 23:46:26 1.382 @@ -880,7 +880,7 @@ AnyEvent::Impl::Irssi used when running within irssi. AnyEvent::Impl::IOAsync based on IO::Async. AnyEvent::Impl::Cocoa based on Cocoa::EventLoop. - AnyEvent::Impl::FLTK2 based on FLTK (fltk 2 binding). + AnyEvent::Impl::FLTK based on FLTK (fltk 2 binding). =item Backends with special needs. @@ -1055,11 +1055,19 @@ Log the given C<$msg> at the given C<$level>. -Loads AnyEvent::Log on first use and calls C - -consequently, look at the L documentation for details. +If L is not loaded then this function makes a simple test +to see whether the message will be logged. If the test succeeds it will +load AnyEvent::Log and call C - consequently, look at +the L documentation for details. + +If the test fails it will simply return. Right now this happens when a +numerical loglevel is used and it is larger than the level specified via +C<$ENV{PERL_ANYEVENT_VERBOSE}>. If you want to sprinkle loads of logging calls around your code, consider -creating a logger callback with the C function, +which can reduce typing, codesize and can reduce the logging overhead +enourmously. =back @@ -1129,7 +1137,7 @@ AnyEvent as a client and can therefore be mixed easily with other AnyEvent modules and other event loops in the same program. Some of the modules come as part of AnyEvent, the others are available via CPAN (see -L for +L for a longer non-exhaustive list), and the list is heavily biased towards modules of the AnyEvent author himself :) @@ -1162,35 +1170,31 @@ the curious, IGS is the International Go Server and FCP is the Freenet Client Protocol). -=item L +=item L + +Truly asynchronous (as opposed to non-blocking) I/O, should be in the +toolbox of every event programmer. AnyEvent::AIO transparently fuses +L and AnyEvent together, giving AnyEvent access to event-based +file I/O, and much more. -Here be danger! +=item L -As Pauli would put it, "Not only is it not right, it's not even wrong!" - -there are so many things wrong with AnyEvent::Handle::UDP, most notably -its use of a stream-based API with a protocol that isn't streamable, that -the only way to improve it is to delete it. - -It features data corruption (but typically only under load) and general -confusion. On top, the author is not only clueless about UDP but also -fact-resistant - some gems of his understanding: "connect doesn't work -with UDP", "UDP packets are not IP packets", "UDP only has datagrams, not -packets", "I don't need to implement proper error checking as UDP doesn't -support error checking" and so on - he doesn't even understand what's -wrong with his module when it is explained to him. +AnyEvent is good for non-blocking stuff, but it can't detect file or +path changes (e.g. "watch this directory for new files", "watch this +file for changes"). The L module promises to +do just that in a portbale fashion, supporting inotify on GNU/Linux and +some weird, without doubt broken, stuff on OS X to monitor files. It can +fall back to blocking scans at regular intervals transparently on other +platforms, so it's about as portable as it gets. + +(I haven't used it myself, but I haven't heard anybody complaining about +it yet). =item L Executes L requests asynchronously in a proxy process for you, notifying you in an event-based way when the operation is finished. -=item L - -Truly asynchronous (as opposed to non-blocking) I/O, should be in the -toolbox of every event programmer. AnyEvent::AIO transparently fuses -L and AnyEvent together, giving AnyEvent access to event-based -file I/O, and much more. - =item L A simple embedded webserver. @@ -1201,7 +1205,19 @@ =item L -Has special support for AnyEvent via L. +Has special support for AnyEvent via L, which allows you +to simply invert the flow control - don't call us, we will call you: + + async { + Coro::AnyEvent::sleep 5; # creates a 5s timer and waits for it + print "5 seconds later!\n"; + + Coro::AnyEvent::readable *STDIN; # uses an I/O watcher + my $line = ; # works for ttys + + AnyEvent::HTTP::http_get "url", Coro::rouse_cb; + my ($body, $hdr) = Coro::rouse_wait; + }; =back @@ -1221,14 +1237,13 @@ use Carp (); -our $VERSION = '6.01'; +our $VERSION = '6.02'; our $MODEL; - our @ISA; - our @REGISTRY; - our $VERBOSE; +our $MAX_SIGNAL_LATENCY = 10; +our %PROTOCOL; # (ipv4|ipv6) => (1|2), higher numbers are preferred BEGIN { require "AnyEvent/constants.pl"; @@ -1238,14 +1253,16 @@ delete @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} if ${^TAINT}; - $VERBOSE = $ENV{PERL_ANYEVENT_VERBOSE}*1; -} + $ENV{"PERL_ANYEVENT_$_"} = $ENV{"AE_$_"} + for grep s/^AE_// && !exists $ENV{"PERL_ANYEVENT_$_"}, keys %ENV; -our $MAX_SIGNAL_LATENCY = 10; + @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} = () + if ${^TAINT}; -our %PROTOCOL; # (ipv4|ipv6) => (1|2), higher numbers are preferred + # $ENV{PERL_ANYEVENT_xxx} now valid + + $VERBOSE = length $ENV{PERL_ANYEVENT_VERBOSE} ? $ENV{PERL_ANYEVENT_VERBOSE}*1 : 3; -{ my $idx; $PROTOCOL{$_} = ++$idx for reverse split /\s*,\s*/, @@ -1287,9 +1304,18 @@ } sub log($$;@) { - require AnyEvent::Log; - # AnyEvent::Log overwrites this function - goto &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; + # AnyEvent::Log overwrites this function + goto &log; + } + + 0 # not logged +} + +if (length $ENV{PERL_ANYEVENT_LOG}) { + require AnyEvent::Log; # AnyEvent::Log does the thing for us } our @models = ( @@ -1309,7 +1335,7 @@ [Prima:: => AnyEvent::Impl::POE::], [IO::Async::Loop:: => AnyEvent::Impl::IOAsync::], # a bitch to autodetect [Cocoa::EventLoop:: => AnyEvent::Impl::Cocoa::], - [FLTK:: => AnyEvent::Impl::FLTK2::], + [FLTK:: => AnyEvent::Impl::FLTK::], ); our @isa_hook; @@ -1357,11 +1383,10 @@ my $model = $1; $model = "AnyEvent::Impl::$model" unless $model =~ s/::$//; if (eval "require $model") { + AnyEvent::log 7 => "loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it."; $MODEL = $model; - AnyEvent::log 7 => "loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it." - if $VERBOSE >= 7; } else { - AnyEvent::log warn => "unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@"; + AnyEvent::log 5 => "unable to load model '$model' (from \$ENV{PERL_ANYEVENT_MODEL}):\n$@"; } } @@ -1371,9 +1396,8 @@ my ($package, $model) = @$_; if (${"$package\::VERSION"} > 0) { if (eval "require $model") { + AnyEvent::log 7 => "autodetected model '$model', using it."; $MODEL = $model; - AnyEvent::log 7 => "autodetected model '$model', using it." - if $VERBOSE >= 7; last; } } @@ -1389,9 +1413,8 @@ and ${"$package\::VERSION"} > 0 and eval "require $model" ) { + AnyEvent::log 7 => "autoloaded model '$model', using it."; $MODEL = $model; - AnyEvent::log 7 => "autoloaded model '$model', using it." - if $VERBOSE >= 7; last; } } @@ -1551,18 +1574,17 @@ eval q{ # poor man's autoloading {} # probe for availability of Time::HiRes if (eval "use Time::HiRes (); Time::HiRes::time (); 1") { - AnyEvent::log 8 => "AnyEvent: using Time::HiRes for sub-second timing accuracy." - if $AnyEvent::VERBOSE >= 8; *time = sub { Time::HiRes::time () }; *AE::time = \& Time::HiRes::time ; + *now = \&time; + AnyEvent::log 8 => "AnyEvent: using Time::HiRes for sub-second timing accuracy."; # if (eval "use POSIX (); (POSIX::times())... } else { - AnyEvent::log critical => "using built-in time(), WARNING, no sub-second resolution!"; *time = sub { CORE::time }; *AE::time = sub (){ CORE::time }; + *now = \&time; + AnyEvent::log 3 => "using built-in time(), WARNING, no sub-second resolution!"; } - - *now = \&time; }; die if $@; @@ -1665,15 +1687,13 @@ eval q{ # poor man's autoloading {} # probe for availability of Async::Interrupt if (_have_async_interrupt) { - AnyEvent::log 8 => "using Async::Interrupt for race-free signal handling." - if $AnyEvent::VERBOSE >= 8; + AnyEvent::log 8 => "using Async::Interrupt for race-free signal handling."; $SIGPIPE_R = new Async::Interrupt::EventPipe; $SIG_IO = AE::io $SIGPIPE_R->fileno, 0, \&_signal_exec; } else { - AnyEvent::log 8 => "using emulated perl signal handling with latency timer." - if $AnyEvent::VERBOSE >= 8; + AnyEvent::log 8 => "using emulated perl signal handling with latency timer."; if (AnyEvent::WIN32) { require AnyEvent::Util; @@ -1977,31 +1997,89 @@ =head1 ENVIRONMENT VARIABLES -The following environment variables are used by this module or its -submodules. +AnyEvent supports a number of environment variables that tune the +runtime behaviour. They are usually evaluated when AnyEvent is +loaded, initialised, or a submodule that uses them is loaded. Many of +them also cause AnyEvent to load additional modules - for example, +C causes the L module to be +loaded. + +All the environment variables documented here start with +C, which is what AnyEvent considers its own +namespace. Other modules are encouraged (but by no means required) to use +C if they have registered the AnyEvent::Submodule +namespace on CPAN, for any submodule. For example, L could +be expected to use C (it should not access env +variables starting with C, see below). + +All variables can also be set via the C prefix, that is, instead +of setting C you can also set C. In +case there is a clash btween anyevent and another program that uses +C you can set the corresponding C +variable to the empty string, as those variables take precedence. + +When AnyEvent is first loaded, it copies all C env variables +to their C counterpart unless that variable already +exists. If taint mode is on, then AnyEvent will remove I environment +variables starting with C from C<%ENV> (or replace them +with C or the empty string, if the corresaponding C variable +is set). + +The exact algorithm is currently: + + 1. if taint mode enabled, delete all PERL_ANYEVENT_xyz variables from %ENV + 2. copy over AE_xyz to PERL_ANYEVENT_xyz unless the latter alraedy exists + 3. if taint mode enabled, set all PERL_ANYEVENT_xyz variables to undef. + +This ensures that child processes will not see the C variables. -Note that AnyEvent will remove I environment variables starting with -C from C<%ENV> when it is loaded while taint mode is -enabled. +The following environment variables are currently known to AnyEvent: =over 4 =item C -By default, AnyEvent will be completely silent except in fatal -conditions. You can set this environment variable to make AnyEvent more -talkative. - -When set to C<5> or higher, causes AnyEvent to warn about unexpected -conditions, such as not being able to load the event model specified by -C. +By default, AnyEvent will only log messages with loglevel C<3> +(C) or higher (see L). You can set this +environment variable to a numerical loglevel to make AnyEvent more (or +less) talkative. + +If you want to do more than just set the global logging level +you should have a look at C, which allows much more +complex specifications. + +When set to C<0> (C), then no messages whatsoever will be logged with +the default logging settings. + +When set to C<5> or higher (C), causes AnyEvent to warn about +unexpected conditions, such as not being able to load the event model +specified by C, or a guard callback throwing an +exception - this is the minimum recommended level. -When set to C<7> or higher, cause AnyEvent to report to STDERR which event -model it chooses. +When set to C<7> or higher (info), cause AnyEvent to report which event model it +chooses. -When set to C<8> or higher, then AnyEvent will report extra information on +When set to C<8> or higher (debug), then AnyEvent will report extra information on which optional modules it loads and how it implements certain features. +=item C + +Accepts rather complex logging specifications. For example, you could log +all C messages of some module to stderr, warnings and above to +stderr, and errors and above to syslog, with: + + PERL_ANYEVENT_LOG=Some::Module=debug,+log:filter=warn,+%syslog:%syslog=error,syslog + +For the rather extensive details, see L. + +This variable is evaluated when AnyEvent (or L) is loaded, +so will take effect even before AnyEvent has initialised itself. + +Note that specifying this environment variable causes the L +module to be loaded, while C does not, so only +using the latter saves a few hundred kB of memory until the first message +is being logged. + =item C AnyEvent does not do much argument checking by default, as thorough @@ -2024,7 +2102,7 @@ C<$$> by the process pid) and an C is bound on that port. The shell object is saved in C<$AnyEvent::Debug::SHELL>. -This takes place when the first watcher is created. +This happens when the first watcher is created. For example, to bind a debug shell on a unix domain socket in F<< /tmp/debug.sock >>, you could use this: @@ -2080,12 +2158,18 @@ addresses. C support either IPv4 or IPv6, but prefer IPv6 over IPv4. +=item C + +This variable, if specified, overrides the F file used by +LC<::resolve_sockaddr>, i.e. hosts aliases will be read +from that file instead. + =item C -Used by L to decide whether to use the EDNS0 extension -for DNS. This extension is generally useful to reduce DNS traffic, but -some (broken) firewalls drop such DNS packets, which is why it is off by -default. +Used by L to decide whether to use the EDNS0 extension for +DNS. This extension is generally useful to reduce DNS traffic, especially +when DNSSEC is involved, but some (broken) firewalls drop such DNS +packets, which is why it is off by default. Setting this variable to C<1> will cause L to announce EDNS0 in its DNS requests. @@ -2103,16 +2187,16 @@ =item C -The file to use instead of F (or OS-specific -configuration) in the default resolver. When set to the empty string, no -default config will be used. +The absolute path to a F-style file to use instead of +F (or the OS-specific configuration) in the default +resolver, or the empty string to select the default configuration. =item C, C. When neither C nor C was specified during L context creation, and either of these environment -variables exist, they will be used to specify CA certificate locations -instead of a system-dependent default. +variables are nonempty, they will be used to specify CA certificate +locations instead of a system-dependent default. =item C and C