--- AnyEvent/lib/AnyEvent.pm 2008/04/14 19:11:15 1.49 +++ AnyEvent/lib/AnyEvent.pm 2008/05/30 21:43:26 1.147 @@ -1,8 +1,8 @@ -=head1 NAME +=head1 => NAME AnyEvent - provide framework for multiple event loops -Event, Coro, Glib, Tk, Perl - various supported event loops +EV, Event, Glib, Tk, Perl, Event::Lib, Qt, POE - various supported event loops =head1 SYNOPSIS @@ -16,9 +16,9 @@ ... }); - my $w = AnyEvent->condvar; # stores wether a condition was flagged - $w->wait; # enters "main loop" till $condvar gets ->broadcast - $w->broadcast; # wake up current and all future wait's + 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 =head1 WHY YOU SHOULD USE THIS MODULE (OR NOT) @@ -31,8 +31,9 @@ First and foremost, I itself, it only 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, and AnyEvent -helps hiding the differences. +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. 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 @@ -40,31 +41,39 @@ module users into the same thing by forcing them to use the same event model you use. -For modules like POE or IO::Async (which 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. - -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. If your module uses one of -those, every user of your module has to use it, too. If your module -uses AnyEvent, it works transparently with all event models it supports -(including stuff like POE and IO::Async). +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. + +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). -In addition of being free of having to use I, AnyEvent also is free of bloat and policy: with POE or similar -modules, you get an enourmous amount of code and strict rules you have -to follow. AnyEvent, on the other hand, is lean and to the point by only -offering the functionality that is useful, in as thin as a wrapper as +modules, you get an enormous amount of code and strict rules you have to +follow. AnyEvent, on the other hand, is lean and up to the point, by only +offering the functionality that is necessary, in as thin as a wrapper as technically possible. -Of course, if you want lots of policy (this can arguably be somewhat +Of course, AnyEvent comes with a big (and fully optional!) toolbox +of useful functionality, such as an asynchronous DNS resolver, 100% +non-blocking connects (even with TLS/SSL, IPv6 and on broken platforms +such as Windows) and lots of real-world knowledge and workarounds for +platform bugs and differences. + +Now, if you I lots of policy (this can arguably be somewhat useful) and you want to force your users to use the one and only event model, you should I use this module. - =head1 DESCRIPTION L provides an identical interface to multiple event loops. This @@ -72,19 +81,22 @@ users to use the same event loop (as only a single event loop can coexist peacefully at any one time). -The interface itself is vaguely similar but not identical to the Event +The interface itself is vaguely similar, but not identical to the L module. -On the first call of any method, the module tries to detect the currently -loaded event loop by probing wether any of the following modules is -loaded: L, L, L, L. The first one found is -used. If none is found, the module tries to load these modules in the -order given. The first one that could be successfully loaded will be -used. If still none could be found, AnyEvent will fall back to a pure-perl -event loop, which is also not very efficient. +During the first call of any watcher-creation method, the module tries +to detect the currently loaded event loop by probing whether one of the +following modules is already loaded: L, +L, L, L, L, L, L, +L. The first one found is used. If none are found, the module tries +to load these modules (excluding Tk, Event::Lib, Qt and POE as the pure perl +adaptor should always succeed) in the order given. The first one that can +be successfully loaded will be used. If, after this, still none could be +found, AnyEvent will fall back to a pure-perl event loop, which is not +very efficient, but should work everywhere. Because AnyEvent first checks for modules that are already loaded, loading -an Event model explicitly before first using AnyEvent will likely make +an event model explicitly before first using AnyEvent will likely make that model the default. For example: use Tk; @@ -92,40 +104,67 @@ # .. AnyEvent will likely default to Tk +The I means that, if any module loads another event model and +starts using it, all bets are off. Maybe you should tell their authors to +use AnyEvent so their modules work together with others seamlessly... + The pure-perl implementation of AnyEvent is called C. Like other event modules you can load it -explicitly. +explicitly and enjoy the high availability of that event loop :) =head1 WATCHERS AnyEvent has the central concept of a I, which is an object that stores relevant data for each kind of event you are waiting for, such as -the callback to call, the filehandle to watch, etc. +the callback to call, the file handle to watch, etc. These watchers are normal Perl objects with normal Perl lifetime. After -creating a watcher it will immediately "watch" for events and invoke -the callback. To disable the watcher you have to destroy it (e.g. by -setting the variable that stores it to C or otherwise deleting all -references to it). +creating a watcher it will immediately "watch" for events and invoke the +callback when the event occurs (of course, only when the event model +is in control). + +To disable the watcher you have to destroy it (e.g. by setting the +variable you store it in to C or otherwise deleting all references +to it). All watchers are created by calling a method on the C class. -=head2 IO WATCHERS +Many watchers either are used with "recursion" (repeating timers for +example), or need to refer to their watcher object in other ways. -You can create I/O watcher by calling the C<< AnyEvent->io >> method with -the following mandatory arguments: +An any way to achieve that is this pattern: -C the Perl I (not filedescriptor) to watch for -events. C must be a string that is either C or C, that creates -a watcher waiting for "r"eadable or "w"ritable events. C the callback -to invoke everytime the filehandle becomes ready. - -Only one io watcher per C and C combination is allowed (i.e. on -a socket you can have one r + one w, not any more (limitation comes from -Tk - if you are sure you are not using Tk this limitation is gone). - -Filehandles will be kept alive, so as long as the watcher exists, the -filehandle exists, too. + my $w; $w = AnyEvent->type (arg => value ..., cb => sub { + # you can use $w here, for example to undef it + undef $w; + }); + +Note that C combination. This is necessary because in Perl, +my variables are only visible after the statement in which they are +declared. + +=head2 I/O WATCHERS + +You can create an I/O watcher by calling the C<< AnyEvent->io >> method +with the following mandatory key-value pairs as arguments: + +C the Perl I (I file descriptor) to watch +for events. C must be a string that is either C or C, +which creates a watcher waiting for "r"eadable or "w"ritable events, +respectively. C is the callback to invoke each time the file handle +becomes ready. + +Although the callback might get passed parameters, their value and +presence is undefined and you cannot rely on them. Portable AnyEvent +callbacks cannot use arguments passed to I/O watcher callbacks. + +The I/O watcher might use the underlying file descriptor or a copy of it. +You must not close a file handle as long as any watcher is active on the +underlying file descriptor. + +Some event loops issue spurious readyness notifications, so you should +always use non-blocking calls when reading/writing from/to your file +handles. Example: @@ -141,8 +180,13 @@ You can create a time watcher by calling the C<< AnyEvent->timer >> method with the following mandatory arguments: -C after how many seconds (fractions are supported) should the timer -activate. C the callback to invoke. +C specifies after how many seconds (fractional values are +supported) the callback should be invoked. C is the callback to invoke +in that case. + +Although the callback might get passed parameters, their value and +presence is undefined and you cannot rely on them. Portable AnyEvent +callbacks cannot use arguments passed to time watcher callbacks. The timer callback will be invoked at most once: if you want a repeating timer you have to create a new watcher (this is a limitation by both Tk @@ -158,93 +202,403 @@ # to cancel the timer: undef $w; -=head2 CONDITION WATCHERS +Example 2: -Condition watchers can be created by calling the C<< AnyEvent->condvar >> -method without any arguments. + # fire an event after 0.5 seconds, then roughly every second + my $w; -A condition watcher watches for a condition - precisely that the C<< -->broadcast >> method has been called. + my $cb = sub { + # cancel the old timer while creating a new one + $w = AnyEvent->timer (after => 1, cb => $cb); + }; -Note that condition watchers recurse into the event loop - if you have -two watchers that call C<< ->wait >> in a round-robbin fashion, you -lose. Therefore, condition watchers are good to export to your caller, but -you should avoid making a blocking wait, at least in callbacks, as this -usually asks for trouble. + # start the "loop" by creating the first watcher + $w = AnyEvent->timer (after => 0.5, cb => $cb); -The watcher has only two methods: +=head3 TIMING ISSUES + +There are two ways to handle timers: based on real time (relative, "fire +in 10 seconds") and based on wallclock time (absolute, "fire at 12 +o'clock"). + +While most event loops expect timers to specified in a relative way, they +use absolute time internally. This makes a difference when your clock +"jumps", for example, when ntp decides to set your clock backwards from +the wrong date of 2014-01-01 to 2008-01-01, a watcher that is supposed to +fire "after" a second might actually take six years to finally fire. + +AnyEvent cannot compensate for this. The only event loop that is conscious +about these issues is L, which offers both relative (ev_timer, based +on true relative time) and absolute (ev_periodic, based on wallclock time) +timers. + +AnyEvent always prefers relative timers, if available, matching the +AnyEvent API. + +AnyEvent has two additional methods that return the "current time": =over 4 -=item $cv->wait +=item AnyEvent->time -Wait (blocking if necessary) until the C<< ->broadcast >> method has been -called on c<$cv>, while servicing other watchers normally. +This returns the "current wallclock time" as a fractional number of +seconds since the Epoch (the same thing as C