--- AnyEvent/lib/AnyEvent.pm 2009/06/25 11:16:08 1.219 +++ AnyEvent/lib/AnyEvent.pm 2009/07/08 02:01:12 1.229 @@ -178,7 +178,7 @@ You can create an I/O watcher by calling the C<< AnyEvent->io >> method with the following mandatory key-value pairs as arguments: -C is the Perl I (I file descriptor) to watch +C is the Perl I (or a naked file descriptor) to watch for events (AnyEvent might or might not keep a reference to this file handle). Note that only file handles pointing to things for which non-blocking operation makes sense are allowed. This includes sockets, @@ -601,8 +601,6 @@ =item $cv->end -These two methods are EXPERIMENTAL and MIGHT CHANGE. - These two methods can be used to combine many transactions/events into one. For example, a function that pings many hosts in parallel might want to use a condition variable for the whole process. @@ -613,7 +611,37 @@ is I to call C<< ->send >>, but that is not required. If no callback was set, C will be called without any arguments. -Let's clarify this with the ping example: +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 +condition (all C calls must be C'ed before the condvar sends). + +Let's start with a simple example: you have two I/O watchers (for example, +STDOUT and STDERR for a program), and you want to wait for both streams to +close before activating a condvar: + + my $cv = AnyEvent->condvar; + + $cv->begin; # first watcher + my $w1 = AnyEvent->io (fh => $fh1, cb => sub { + defined sysread $fh1, my $buf, 4096 + or $cv->end; + }); + + $cv->begin; # second watcher + my $w2 = AnyEvent->io (fh => $fh2, cb => sub { + defined sysread $fh2, my $buf, 4096 + or $cv->end; + }); + + $cv->recv; + +This works because for every event source (EOF on file handle), there is +one call to C, so the condvar waits for all calls to C before +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 +begung can potentially be zero: my $cv = AnyEvent->condvar; @@ -643,10 +671,11 @@ C is called even when C hosts are being pinged (the loop doesn't execute once). -This is the general pattern when you "fan out" into multiple subrequests: -use an outer C/C pair to set the callback and ensure C -is called at least once, and then, for each subrequest you start, call -C and for each subrequest you finish, call C. +This is the general pattern when you "fan out" into multiple (but +potentially none) subrequests: use an outer C/C pair to set +the callback and ensure C is called at least once, and then, for each +subrequest you start, call C and for each subrequest you finish, +call C. =back @@ -941,7 +970,7 @@ use Carp; -our $VERSION = 4.412; +our $VERSION = 4.8; our $MODEL; our $AUTOLOAD; @@ -1096,12 +1125,10 @@ my ($poll, $fh, $r, $w) = @_; # cygwin requires the fh mode to be matching, unix doesn't - my ($rw, $mode) = $poll eq "r" ? ($r, "<") - : $poll eq "w" ? ($w, ">") - : Carp::croak "AnyEvent->io requires poll set to either 'r' or 'w'"; + my ($rw, $mode) = $poll eq "r" ? ($r, "<") : ($w, ">"); - open my $fh2, "$mode&" . fileno $fh - or die "cannot dup() filehandle: $!,"; + open my $fh2, "$mode&", $fh + or die "AnyEvent->io: cannot dup() filehandle in mode '$poll': $!,"; # we assume CLOEXEC is already set by perl in all important cases @@ -1444,6 +1471,25 @@ The maximum number of child processes that C will create in parallel. +=item C + +The default value for the C parameter for the default DNS +resolver - this is the maximum number of parallel DNS requests that are +sent to the DNS server. + +=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. + +=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. + =back =head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE @@ -1697,6 +1743,8 @@ 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 @@ -1736,6 +1784,9 @@ The C module has a relatively high setup and callback invocation cost, but overall scores in on the third place. +C performs admirably well, about on par with C, even +when using its pure perl backend. + C's memory usage is quite a bit higher, but it features a faster callback invocation and overall ends up in the same class as C. However, Glib scales extremely badly, doubling the number of @@ -1822,12 +1873,14 @@ =head3 Results - name sockets create request - EV 20000 69.01 11.16 - Perl 20000 73.32 35.87 - Event 20000 212.62 257.32 - Glib 20000 651.16 1896.30 - POE 20000 349.67 12317.24 uses POE::Loop::Event + 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 =head3 Discussion @@ -1840,6 +1893,9 @@ Perl surprisingly comes second. It is much faster than the C-based event loops Event and Glib. +IO::Async performs very well when using its epoll backend, and still quite +good compared to Glib when using its pure perl backend. + Event suffers from high setup time as well (look at its code and you will understand why). Callback invocation also has a high overhead compared to the C<< $_->() for .. >>-style loop that the Perl event loop uses. Event