--- AnyEvent/lib/AnyEvent.pm 2012/03/27 16:21:11 1.398 +++ AnyEvent/lib/AnyEvent.pm 2014/08/28 15:26:20 1.419 @@ -2,8 +2,8 @@ AnyEvent - the DBI of event loop programming -EV, Event, Glib, Tk, Perl, Event::Lib, Irssi, rxvt-unicode, IO::Async, Qt, -FLTK and POE are various supported event loops/environments. +EV, Event, Glib, Tk, UV, Perl, Event::Lib, Irssi, rxvt-unicode, IO::Async, +Qt, FLTK and POE are various supported event loops/environments. =head1 SYNOPSIS @@ -273,7 +273,7 @@ my $w = AnyEvent->timer (after => 0.5, interval => 1, cb => sub { warn "timeout\n"; - }; + }); =head3 TIMING ISSUES @@ -489,6 +489,10 @@ my $done = AnyEvent->condvar; + # this forks and immediately calls exit in the child. this + # normally has all sorts of bad consequences for your parent, + # so take this as an example only. always fork and exec, + # or call POSIX::_exit, in real code. my $pid = fork or exit 5; my $w = AnyEvent->child ( @@ -747,7 +751,7 @@ sending. The ping example mentioned above is slightly more complicated, as the -there are results to be passwd back, and the number of tasks that are +there are results to be passed back, and the number of tasks that are begun can potentially be zero: my $cv = AnyEvent->condvar; @@ -765,6 +769,10 @@ $cv->end; + ... + + my $results = $cv->recv; + This code fragment supposedly pings a number of hosts and calls 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 @@ -809,11 +817,15 @@ in scalar context only the first one will be returned. Note that doing a blocking wait in a callback is not supported by any -event loop, that is, recursive invocation of a blocking C<< ->recv ->> is not allowed, and the C call will C if such a -condition is detected. This condition can be slightly loosened by using -L, which allows you to do a blocking C<< ->recv >> from -any thread that doesn't run the event loop itself. +event loop, that is, recursive invocation of a blocking C<< ->recv >> is +not allowed and the C call will C if such a condition is +detected. This requirement can be dropped by relying on L +, which allows you to do a blocking C<< ->recv >> from any thread +that doesn't run the event loop itself. L is loaded +automatically when L is used with L, so code does not need +to do anything special to take advantage of that: any code that would +normally block your program because it calls C, be executed in an +C thread instead without blocking other threads. Not all event models support a blocking wait - some die in that case (programs might want to do that to stay interactive), so I: - # start a conenction attempt unless one is active + # start a connection attempt unless one is active $self->{connect_guard} ||= AnyEvent::Socket::tcp_connect "www.example.net", 80, sub { delete $self->{connect_guard}; ... @@ -1141,24 +1154,24 @@ =over 4 -=item L +=item L (part of the AnyEvent distribution) Contains various utility functions that replace often-used blocking functions such as C with event/callback-based versions. -=item L +=item L (part of the AnyEvent distribution) 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 +=item L (part of the AnyEvent distribution) Provide read and write buffers, manages watchers for reads and writes, supports raw and formatted I/O, I/O queued and fully transparent and non-blocking SSL/TLS (via L). -=item L +=item L (part of the AnyEvent distribution) Provides rich asynchronous DNS resolver capabilities. @@ -1168,13 +1181,24 @@ the curious, IGS is the International Go Server and FCP is the Freenet Client Protocol). -=item L +=item L (part of the AnyEvent distribution) 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, L, L, L + +These let you safely fork new subprocesses, either locally or +remotely (e.g.v ia ssh), using some RPC protocol or not, without +the limitations normally imposed by fork (AnyEvent works fine for +example). Dynamically-resized worker pools are obviously included as well. + +And they are quite tiny and fast as well - "abusing" L +just to exec external programs can easily beat using C and C +(or even C) in most programs. + =item L AnyEvent is good for non-blocking stuff, but it can't detect file or @@ -1185,18 +1209,14 @@ 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). +(I haven't used it myself, but it seems the biggest problem with it is +it quite bad performance). =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 - -A simple embedded webserver. - =item L The fastest ping in the west. @@ -1223,20 +1243,14 @@ package AnyEvent; -# basically a tuned-down version of common::sense -sub common_sense { - # from common:.sense 3.5 - local $^W; - ${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\x3c\x3f\x33\x00\x0f\xf0\x0f\xc0\xf0\xfc\x33\x00"; - # use strict vars subs - NO UTF-8, as Util.pm doesn't like this atm. (uts46data.pl) - $^H |= 0x00000600; +BEGIN { + require "AnyEvent/constants.pl"; + &AnyEvent::common_sense; } -BEGIN { AnyEvent::common_sense } - use Carp (); -our $VERSION = '6.14'; +our $VERSION = '7.07'; our $MODEL; our @ISA; our @REGISTRY; @@ -1245,8 +1259,6 @@ our $MAX_SIGNAL_LATENCY = $ENV{PERL_ANYEVENT_MAX_SIGNAL_LATENCY} || 10; # executes after the BEGIN block below (tainting!) BEGIN { - require "AnyEvent/constants.pl"; - eval "sub TAINT (){" . (${^TAINT}*1) . "}"; delete @ENV{grep /^PERL_ANYEVENT_/, keys %ENV} @@ -1357,6 +1369,7 @@ # everything below here should not be autoloaded [Event::Lib:: => AnyEvent::Impl::EventLib::], # too buggy [Tk:: => AnyEvent::Impl::Tk::], # crashes with many handles + [UV:: => AnyEvent::Impl::UV::], # switched from libev, added back all bugs imaginable [Qt:: => AnyEvent::Impl::Qt::], # requires special main program [POE::Kernel:: => AnyEvent::Impl::POE::], # lasciate ogni speranza [Wx:: => AnyEvent::Impl::POE::], @@ -1398,7 +1411,7 @@ # 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 - that module is broken by\n" + AnyEvent::log fatal => "IO::Async::Loop::AnyEvent detected - that module is broken by\n" . "design, abuses internals and breaks AnyEvent - will not continue." if exists $INC{"IO/Async/Loop/AnyEvent.pm"}; @@ -1419,10 +1432,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."; + AnyEvent::log 7 => "Loaded model '$model' (forced by \$ENV{PERL_ANYEVENT_MODEL}), using it."; $MODEL = $model; } else { - AnyEvent::log 4 => "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$@"; } } @@ -1432,11 +1445,11 @@ my ($package, $model) = @$_; if (${"$package\::VERSION"} > 0) { if (eval "require $model") { - AnyEvent::log 7 => "autodetected model '$model', using it."; + AnyEvent::log 7 => "Autodetected model '$model', using it."; $MODEL = $model; last; } else { - AnyEvent::log 8 => "detected event loop $package, but cannot load '$model', skipping: $@"; + AnyEvent::log 8 => "Detected event loop $package, but cannot load '$model', skipping: $@"; } } } @@ -1450,14 +1463,14 @@ and ${"$package\::VERSION"} > 0 and eval "require $model" ) { - AnyEvent::log 7 => "autoloaded model '$model', using it."; + AnyEvent::log 7 => "Autoloaded model '$model', using it."; $MODEL = $model; last; } } $MODEL - or AnyEvent::log fatal => "AnyEvent: backend autodetection failed - did you properly install AnyEvent?"; + or AnyEvent::log fatal => "Backend autodetection failed - did you properly install AnyEvent?"; } } @@ -1614,13 +1627,13 @@ *time = sub { Time::HiRes::time () }; *AE::time = \& Time::HiRes::time ; *now = \&time; - AnyEvent::log 8 => "AnyEvent: using Time::HiRes for sub-second timing accuracy."; + AnyEvent::log 8 => "using Time::HiRes for sub-second timing accuracy."; # if (eval "use POSIX (); (POSIX::times())... } else { *time = sub { CORE::time }; *AE::time = sub (){ CORE::time }; *now = \&time; - AnyEvent::log 3 => "using built-in time(), WARNING, no sub-second resolution!"; + AnyEvent::log 3 => "Using built-in time(), no sub-second resolution!"; } }; die if $@; @@ -1724,13 +1737,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."; + 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."; + AnyEvent::log 8 => "Using emulated perl signal handling with latency timer."; if (AnyEvent::WIN32) { require AnyEvent::Util; @@ -2180,6 +2193,14 @@ PERL_ANYEVENT_MODEL=Perl perl ... +=item C + +The current file I/O model - see L for more info. + +At the moment, only C (small, pure-perl, synchronous) and +C (truly asynchronous) are supported. The default is C if +L can be loaded, otherwise it is C. + =item C Used by both L and L to determine preferences @@ -2193,7 +2214,7 @@ This variable can effectively be used for denial-of-service attacks against local programs (e.g. when setuid), although the impact is likely -small, as the program has to handle conenction and other failures anyways. +small, as the program has to handle connection and other failures anyways. Examples: C - prefer IPv4 over IPv6, but support both and try to use both. C @@ -2915,6 +2936,16 @@ pure-perl event loop (L) will additionally load it to try to use a monotonic clock for timing stability. +=item L (and L) + +The default implementation of L is to do I/O synchronously, +stopping programs while they access the disk, which is fine for a lot of +programs. + +Installing AnyEvent::AIO (and its IO::AIO dependency) makes it switch to +a true asynchronous implementation, so event processing can continue even +while waiting for disk I/O. + =back @@ -2935,17 +2966,35 @@ 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. +something completely out of the scope of AnyEvent (see below). 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 +parent and child, which is almost never what you want. Using C +to start worker children from some kind of manage prrocess is usually preferred, because it is much easier and cleaner, at the expense of having to have another binary. +In addition to logical problems with fork, there are also implementation +problems. For example, on POSIX systems, you cannot fork at all in Perl +code if a thread (I am talking of pthreads here) was ever created in the +process, and this is just the tip of the iceberg. In general, using fork +from Perl is difficult, and attempting to use fork without an exec to +implement some kind of parallel processing is almost certainly doomed. + +To safely fork and exec, you should use a module such as +L that let's you safely fork and exec new processes. + +If you want to do multiprocessing using processes, you can +look at the L module (and some related modules +such as L, L and +L). This module allows you to safely create +subprocesses without any limitations - you can use X11 toolkits or +AnyEvent in the children created by L safely and without +any special precautions. + =head1 SECURITY CONSIDERATIONS @@ -3007,6 +3056,8 @@ Non-blocking handles, pipes, stream sockets, TCP clients and servers: L, L, L. +Asynchronous File I/O: L. + Asynchronous DNS: L. Thread support: L, L, L, L. @@ -3018,7 +3069,7 @@ =head1 AUTHOR Marc Lehmann - http://home.schmorp.de/ + http://anyevent.schmorp.de =cut