--- AnyEvent/lib/AnyEvent.pm 2008/07/08 23:44:51 1.167 +++ AnyEvent/lib/AnyEvent.pm 2008/11/05 02:21:27 1.190 @@ -8,17 +8,26 @@ use AnyEvent; - my $w = AnyEvent->io (fh => $fh, poll => "r|w", cb => sub { - ... - }); + my $w = AnyEvent->io (fh => $fh, poll => "r|w", cb => sub { ... }); + + my $w = AnyEvent->timer (after => $seconds, cb => sub { ... }); + my $w = AnyEvent->timer (after => $seconds, interval => $seconds, cb => ... - my $w = AnyEvent->timer (after => $seconds, cb => sub { + print AnyEvent->now; # prints current event loop time + print AnyEvent->time; # think Time::HiRes::time or simply CORE::time. + + my $w = AnyEvent->signal (signal => "TERM", cb => sub { ... }); + + my $w = AnyEvent->child (pid => $pid, cb => sub { + my ($pid, $status) = @_; ... }); my $w = AnyEvent->condvar; # stores whether a condition was flagged $w->send; # wake up current and all future recv's $w->recv; # enters "main loop" till $condvar gets ->send + # use a condvar in callback mode: + $w->cb (sub { $_[0]->recv }); =head1 INTRODUCTION/TUTORIAL @@ -35,11 +44,12 @@ policy> and AnyEvent is I. First and foremost, I itself, it only -interfaces to whatever event model the main program happens to use in a +interfaces to whatever event model the main program happens to use, in a pragmatic way. For event models and certain classes of immortals alike, the statement "there can only be one" is a bitter reality: In general, only one event loop can be active at the same time in a process. AnyEvent -helps hiding the differences between those event loops. +cannot change this, but it can hide the differences between those event +loops. The goal of AnyEvent is to offer module authors the ability to do event programming (waiting for I/O or timer events) without subscribing to a @@ -50,18 +60,18 @@ For modules like POE or IO::Async (which is a total misnomer as it is actually doing all I/O I...), using them in your module is like joining a cult: After you joined, you are dependent on them and you -cannot use anything else, as it is simply incompatible to everything that -isn't itself. What's worse, all the potential users of your module are -I forced to use the same event loop you use. +cannot use anything else, as they are simply incompatible to everything +that isn't them. What's worse, all the potential users of your +module are I forced to use the same event loop you use. AnyEvent is different: AnyEvent + POE works fine. AnyEvent + Glib works fine. AnyEvent + Tk works fine etc. etc. but none of these work together with the rest: POE + IO::Async? No go. Tk + Event? No go. Again: if your module uses one of those, every user of your module has to use it, too. But if your module uses AnyEvent, it works transparently with all -event models it supports (including stuff like POE and IO::Async, as long -as those use one of the supported event loops. It is trivial to add new -event loops to AnyEvent, too, so it is future-proof). +event models it supports (including stuff like IO::Async, as long as those +use one of the supported event loops. It is trivial to add new event loops +to AnyEvent, too, so it is future-proof). In addition to being free of having to use I, AnyEvent also is free of bloat and policy: with POE or similar @@ -332,11 +342,18 @@ You can also watch on a child process exit and catch its exit status. The child process is specified by the C argument (if set to C<0>, it -watches for any child process exit). The watcher will trigger as often -as status change for the child are received. This works by installing a -signal handler for C. The callback will be called with the pid -and exit status (as returned by waitpid), so unlike other watcher types, -you I rely on child watcher callback arguments. +watches for any child process exit). The watcher will triggered only when +the child process has finished and an exit status is available, not on +any trace events (stopped/continued). + +The callback will be called with the pid and exit status (as returned by +waitpid), so unlike other watcher types, you I rely on child watcher +callback arguments. + +This watcher type works by installing a signal handler for C, +and since it cannot be shared, nothing else should use SIGCHLD or reap +random child processes (waiting for specific child processes, e.g. inside +C, is just fine). There is a slight catch to child watchers, however: you usually start them I the child process was created, and this means the process could @@ -382,8 +399,10 @@ Condition variables can be created by calling the C<< AnyEvent->condvar >> method, usually without arguments. The only argument pair allowed is + C, which specifies a callback to be called when the condition variable -becomes true. +becomes true, with the condition variable as the first argument (but not +the results). After creation, the condition variable is "false" until it becomes "true" by calling the C method (or calling the condition variable as if it @@ -449,6 +468,23 @@ my $delay = AnyEvent->timer (after => 5, cb => $done); $done->recv; +Example: Imagine an API that returns a condvar and doesn't support +callbacks. This is how you make a synchronous call, for example from +the main program: + + use AnyEvent::CouchDB; + + ... + + my @info = $couchdb->info->recv; + +And this is how you would just ste a callback to be called whenever the +results are available: + + $couchdb->info->cb (sub { + my @info = $_[0]->recv; + }); + =head3 METHODS FOR PRODUCERS These methods should only be used by the producing side, i.e. the @@ -591,7 +627,7 @@ Returns true when the condition is "true", i.e. whether C or C have been called. -=item $cb = $cv->cb ([new callback]) +=item $cb = $cv->cb ($cb->($cv)) This is a mutator function that returns the callback set and optionally replaces it before doing so. @@ -791,9 +827,9 @@ A non-blocking interface to the Internet Go Server protocol (used by L). -=item L +=item L -AnyEvent based IRC client module family. +AnyEvent based IRC client module family (replacing the older Net::IRC3). =item L @@ -823,11 +859,11 @@ package AnyEvent; no warnings; -use strict; +use strict qw(vars subs); use Carp; -our $VERSION = 4.2; +our $VERSION = 4.32; our $MODEL; our $AUTOLOAD; @@ -942,12 +978,9 @@ push @{"$MODEL\::ISA"}, "AnyEvent::Base"; - if ($ENV{PERL_ANYEVENT_STRICT}) { - unshift @AnyEvent::Base::Strict::ISA, $MODEL; - unshift @ISA, AnyEvent::Base::Strict:: - } else { - unshift @ISA, $MODEL; - } + unshift @ISA, $MODEL; + + require AnyEvent::Strict if $ENV{PERL_ANYEVENT_STRICT}; (shift @post_detect)->() while @post_detect; } @@ -967,14 +1000,42 @@ $class->$func (@_); } +# utility function to dup a filehandle. this is used by many backends +# to support binding more than one watcher per filehandle (they usually +# allow only one watcher per fd, so we dup it to get a different one). +sub _dupfh($$$$) { + my ($poll, $fh, $r, $w) = @_; + + require Fcntl; + + # 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'"; + + open my $fh2, "$mode&" . fileno $fh + or die "cannot dup() filehandle: $!"; + + # we assume CLOEXEC is already set by perl in all important cases + + ($fh2, $rw) +} + package AnyEvent::Base; # default implementation for now and time -use Time::HiRes (); +BEGIN { + if (eval "use Time::HiRes (); time (); 1") { + *_time = \&Time::HiRes::time; + # if (eval "use POSIX (); (POSIX::times())... + } else { + *_time = sub { time }; # epic fail + } +} -sub time { Time::HiRes::time } -sub now { Time::HiRes::time } +sub time { _time } +sub now { _time } # default implementation for ->condvar @@ -1123,170 +1184,28 @@ *broadcast = \&send; *wait = \&_wait; -package AnyEvent::Base::Strict; - -use Carp qw(croak); - -# supply checks for argument validity for many functions - -sub io { - my $class = shift; - my %arg = @_; - - ref $arg{cb} - or croak "AnyEvent->io called with illegal cb argument '$arg{cb}'"; - delete $arg{cb}; - - fileno $arg{fh} - or croak "AnyEvent->io called with illegal fh argument '$arg{fh}'"; - delete $arg{fh}; - - $arg{poll} =~ /^[rw]$/ - or croak "AnyEvent->io called with illegal poll argument '$arg{poll}'"; - delete $arg{poll}; - - croak "AnyEvent->io called with unsupported parameter(s) " . join ", ", keys %arg - if keys %arg; - - $class->SUPER::io (@_) -} - -sub timer { - my $class = shift; - my %arg = @_; - - ref $arg{cb} - or croak "AnyEvent->timer called with illegal cb argument '$arg{cb}'"; - delete $arg{cb}; - - exists $arg{after} - or croak "AnyEvent->timer called without mandatory 'after' parameter"; - delete $arg{after}; - - $arg{interval} > 0 || !$arg{interval} - or croak "AnyEvent->timer called with illegal interval argument '$arg{interval}'"; - delete $arg{interval}; - - croak "AnyEvent->timer called with unsupported parameter(s) " . join ", ", keys %arg - if keys %arg; - - $class->SUPER::timer (@_) -} - -sub signal { - my $class = shift; - my %arg = @_; - - ref $arg{cb} - or croak "AnyEvent->signal called with illegal cb argument '$arg{cb}'"; - delete $arg{cb}; - - eval "require POSIX; defined &POSIX::SIG$arg{signal}" - or croak "AnyEvent->signal called with illegal signal name '$arg{signal}'"; - delete $arg{signal}; - - croak "AnyEvent->signal called with unsupported parameter(s) " . join ", ", keys %arg - if keys %arg; - - $class->SUPER::signal (@_) -} - -sub child { - my $class = shift; - my %arg = @_; - - ref $arg{cb} - or croak "AnyEvent->signal called with illegal cb argument '$arg{cb}'"; - delete $arg{cb}; - - $arg{pid} =~ /^-?\d+$/ - or croak "AnyEvent->signal called with illegal pid value '$arg{pid}'"; - delete $arg{pid}; - - croak "AnyEvent->signal called with unsupported parameter(s) " . join ", ", keys %arg - if keys %arg; - - $class->SUPER::child (@_) -} - -sub condvar { - my $class = shift; - my %arg = @_; - - !exists $arg{cb} or ref $arg{cb} - or croak "AnyEvent->condvar called with illegal cb argument '$arg{cb}'"; - delete $arg{cb}; - - croak "AnyEvent->condvar called with unsupported parameter(s) " . join ", ", keys %arg - if keys %arg; - - $class->SUPER::condvar (@_) -} - -sub time { - my $class = shift; - - @_ - and croak "AnyEvent->time wrongly called with paramaters"; - - $class->SUPER::time (@_) -} - -sub now { - my $class = shift; - - @_ - and croak "AnyEvent->now wrongly called with paramaters"; - - $class->SUPER::now (@_) -} - -=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE - -This is an advanced topic that you do not normally need to use AnyEvent in -a module. This section is only of use to event loop authors who want to -provide AnyEvent compatibility. - -If you need to support another event library which isn't directly -supported by AnyEvent, you can supply your own interface to it by -pushing, before the first watcher gets created, the package name of -the event module and the package name of the interface to use onto -C<@AnyEvent::REGISTRY>. You can do that before and even without loading -AnyEvent, so it is reasonably cheap. - -Example: - - push @AnyEvent::REGISTRY, [urxvt => urxvt::anyevent::]; - -This tells AnyEvent to (literally) use the C -package/class when it finds the C package/module is already loaded. - -When AnyEvent is loaded and asked to find a suitable event model, it -will first check for the presence of urxvt by trying to C the -C module. - -The class should provide implementations for all watcher types. See -L (source code), L (Source code) -and so on for actual examples. Use C to -see the sources. +=head1 ERROR AND EXCEPTION HANDLING -If you don't provide C and C watchers than AnyEvent will -provide suitable (hopefully) replacements. - -The above example isn't fictitious, the I (a.k.a. urxvt) -terminal emulator uses the above line as-is. An interface isn't included -in AnyEvent because it doesn't make sense outside the embedded interpreter -inside I, and it is updated and maintained as part of the -I distribution. - -I also cheats a bit by not providing blocking access to -condition variables: code blocking while waiting for a condition will -C. This still works with most modules/usages, and blocking calls must -not be done in an interactive application, so it makes sense. +In general, AnyEvent does not do any error handling - it relies on the +caller to do that if required. The L module (see also +the C environment variable, below) provides strict +checking of all AnyEvent methods, however, which is highly useful during +development. + +As for exception handling (i.e. runtime errors and exceptions thrown while +executing a callback), this is not only highly event-loop specific, but +also not in any way wrapped by this module, as this is the job of the main +program. + +The pure perl event loop simply re-throws the exception (usually +within C<< condvar->recv >>), the L and L modules call C<< +$Event/EV::DIED->() >>, L uses C<< install_exception_handler >> and +so on. =head1 ENVIRONMENT VARIABLES -The following environment variables are used by this module: +The following environment variables are used by this module or its +submodules: =over 4 @@ -1307,10 +1226,15 @@ AnyEvent does not do much argument checking by default, as thorough argument checking is very costly. Setting this variable to a true value -will cause AnyEvent to thoroughly check the arguments passed to most -method calls and croaks if it finds any problems. In other words, enables -"strict" mode. Unlike C it is definitely recommended ot keep -it off in production. +will cause AnyEvent to load C and then to thoroughly +check the arguments passed to most method calls. If it finds any problems +it will croak. + +In other words, enables "strict" mode. + +Unlike C, it is definitely recommended ot keep it off in +production. Keeping C in your environment while +developing programs can be very useful, however. =item C @@ -1366,6 +1290,49 @@ =back +=head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE + +This is an advanced topic that you do not normally need to use AnyEvent in +a module. This section is only of use to event loop authors who want to +provide AnyEvent compatibility. + +If you need to support another event library which isn't directly +supported by AnyEvent, you can supply your own interface to it by +pushing, before the first watcher gets created, the package name of +the event module and the package name of the interface to use onto +C<@AnyEvent::REGISTRY>. You can do that before and even without loading +AnyEvent, so it is reasonably cheap. + +Example: + + push @AnyEvent::REGISTRY, [urxvt => urxvt::anyevent::]; + +This tells AnyEvent to (literally) use the C +package/class when it finds the C package/module is already loaded. + +When AnyEvent is loaded and asked to find a suitable event model, it +will first check for the presence of urxvt by trying to C the +C module. + +The class should provide implementations for all watcher types. See +L (source code), L (Source code) +and so on for actual examples. Use C to +see the sources. + +If you don't provide C and C watchers than AnyEvent will +provide suitable (hopefully) replacements. + +The above example isn't fictitious, the I (a.k.a. urxvt) +terminal emulator uses the above line as-is. An interface isn't included +in AnyEvent because it doesn't make sense outside the embedded interpreter +inside I, and it is updated and maintained as part of the +I distribution. + +I also cheats a bit by not providing blocking access to +condition variables: code blocking while waiting for a condition will +C. This still works with most modules/usages, and blocking calls must +not be done in an interactive application, so it makes sense. + =head1 EXAMPLE PROGRAM The following program uses an I/O watcher to read data from STDIN, a timer @@ -1568,16 +1535,16 @@ =head3 Results name watchers bytes create invoke destroy comment - EV/EV 400000 244 0.56 0.46 0.31 EV native interface - EV/Any 100000 244 2.50 0.46 0.29 EV + AnyEvent watchers - CoroEV/Any 100000 244 2.49 0.44 0.29 coroutines + Coro::Signal - Perl/Any 100000 513 4.92 0.87 1.12 pure perl implementation - Event/Event 16000 516 31.88 31.30 0.85 Event native interface - Event/Any 16000 590 35.75 31.42 1.08 Event + AnyEvent watchers - Glib/Any 16000 1357 98.22 12.41 54.00 quadratic behaviour - Tk/Any 2000 1860 26.97 67.98 14.00 SEGV with >> 2000 watchers - POE/Event 2000 6644 108.64 736.02 14.73 via POE::Loop::Event - POE/Select 2000 6343 94.13 809.12 565.96 via POE::Loop::Select + 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 + 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 =head3 Discussion @@ -1789,6 +1756,42 @@ =back +=head1 SIGNALS + +AnyEvent currently installs handlers for these signals: + +=over 4 + +=item SIGCHLD + +A handler for C is installed by AnyEvent's child watcher +emulation for event loops that do not support them natively. Also, some +event loops install a similar handler. + +=item SIGPIPE + +A no-op handler is installed for C when C<$SIG{PIPE}> is C +when AnyEvent gets loaded. + +The rationale for this is that AnyEvent users usually do not really depend +on SIGPIPE delivery (which is purely an optimisation for shell use, or +badly-written programs), but C can cause spurious and rare +program exits as a lot of people do not expect C when writing to +some random socket. + +The rationale for installing a no-op handler as opposed to ignoring it is +that this way, the handler will be restored to defaults on exec. + +Feel free to install your own handler, or reset it to defaults. + +=back + +=cut + +$SIG{PIPE} = sub { } + unless defined $SIG{PIPE}; + + =head1 FORK Most event libraries are not fork-safe. The ones who are usually are