--- cvsroot/EV/EV.pm 2007/12/22 16:48:33 1.80 +++ cvsroot/EV/EV.pm 2010/10/21 15:13:42 1.129 @@ -4,73 +4,124 @@ =head1 SYNOPSIS - use EV; - - # TIMERS - - my $w = EV::timer 2, 0, sub { - warn "is called after 2s"; - }; - - my $w = EV::timer 2, 2, sub { - warn "is called roughly every 2s (repeat = 2)"; - }; - - undef $w; # destroy event watcher again - - my $w = EV::periodic 0, 60, 0, sub { - warn "is called every minute, on the minute, exactly"; - }; - - # IO - - my $w = EV::io *STDIN, EV::READ, sub { - my ($w, $revents) = @_; # all callbacks receive the watcher and event mask - warn "stdin is readable, you entered: ", ; - }; - - # SIGNALS + use EV; + + # TIMERS + + my $w = EV::timer 2, 0, sub { + warn "is called after 2s"; + }; + + my $w = EV::timer 2, 2, sub { + warn "is called roughly every 2s (repeat = 2)"; + }; + + undef $w; # destroy event watcher again + + my $w = EV::periodic 0, 60, 0, sub { + warn "is called every minute, on the minute, exactly"; + }; + + # IO + + my $w = EV::io *STDIN, EV::READ, sub { + my ($w, $revents) = @_; # all callbacks receive the watcher and event mask + warn "stdin is readable, you entered: ", ; + }; + + # SIGNALS + + my $w = EV::signal 'QUIT', sub { + warn "sigquit received\n"; + }; + + # CHILD/PID STATUS CHANGES - my $w = EV::signal 'QUIT', sub { - warn "sigquit received\n"; - }; + my $w = EV::child 666, 0, sub { + my ($w, $revents) = @_; + my $status = $w->rstatus; + }; - # CHILD/PID STATUS CHANGES + # STAT CHANGES + my $w = EV::stat "/etc/passwd", 10, sub { + my ($w, $revents) = @_; + warn $w->path, " has changed somehow.\n"; + }; + + # MAINLOOP + EV::loop; # loop until EV::unloop is called or all watchers stop + EV::loop EV::LOOP_ONESHOT; # block until at least one event could be handled + EV::loop EV::LOOP_NONBLOCK; # try to handle same events, but do not block + +=head1 BEFORE YOU START USING THIS MODULE + +If you only need timer, I/O, signal, child and idle watchers and not the +advanced functionality of this module, consider using L instead, +specifically the simplified API described in L. - my $w = EV::child 666, sub { - my ($w, $revents) = @_; - my $status = $w->rstatus; - }; - - # STAT CHANGES - my $w = EV::stat "/etc/passwd", 10, sub { - my ($w, $revents) = @_; - warn $w->path, " has changed somehow.\n"; - }; - - # MAINLOOP - EV::loop; # loop until EV::unloop is called or all watchers stop - EV::loop EV::LOOP_ONESHOT; # block until at least one event could be handled - EV::loop EV::LOOP_NONBLOCK; # try to handle same events, but do not block +When used with EV as backend, the L API is as fast as the native L +API, but your programs/modules will still run with many other event loops. =head1 DESCRIPTION This module provides an interface to libev (L). While the documentation -below is comprehensive, one might also consult the documentation of libev -itself (L) for more subtle details on -watcher semantics or some discussion on the available backends, or how to -force a specific backend with C, or just about in any case -because it has much more detailed information. +below is comprehensive, one might also consult the documentation of +libev itself (L or +F) for more subtle details on watcher semantics or some +discussion on the available backends, or how to force a specific backend +with C, or just about in any case because it has much more +detailed information. + +This module is very fast and scalable. It is actually so fast that you +can use it through the L module, stay portable to other event +loops (if you don't rely on any watcher types not available through it) +and still be faster than with any other event loop currently supported in +Perl. + +=head2 PORTING FROM EV 3.X to 4.X + +EV version 4 introduces a number of incompatible changes summarised +here. According to the depreciation strategy used by libev, there is a +compatibility layer in place so programs should continue to run unchanged +(the XS interface lacks this layer, so programs using that one need to be +updated). + +This compatibility layer will be switched off in some future release. + +All changes relevant to Perl are renames of symbols, functions and +methods: + + EV::loop => EV::run + EV::LOOP_NONBLOCK => EV::RUN_NOWAIT + EV::LOOP_ONESHOT => EV::RUN_ONCE + + EV::unloop => EV::break + EV::UNLOOP_CANCEL => EV::BREAK_CANCEL + EV::UNLOOP_ONE => EV::BREAK_ONE + EV::UNLOOP_ALL => EV::BREAK_ALL + + EV::TIMEOUT => EV::TIMER + + EV::loop_count => EV::iteration + EV::loop_depth => EV::depth + EV::loop_verify => EV::verify + +The loop object methods corresponding to the functions above have been +similarly renamed. + +=head2 MODULE EXPORTS + +This module does not export any symbols. =cut package EV; -use strict; +use common::sense; BEGIN { - our $VERSION = '2.0'; + our $VERSION = '4.00'; use XSLoader; XSLoader::load "EV", $VERSION; } @@ -86,6 +137,7 @@ @EV::Check::ISA = @EV::Embed::ISA = @EV::Fork::ISA = +@EV::Async::ISA = "EV::Watcher"; @EV::Loop::Default::ISA = "EV::Loop"; @@ -106,31 +158,49 @@ For specific programs you can create additional event loops dynamically. +If you want to take advantage of kqueue (which often works properly for +sockets only) even though the default loop doesn't enable it, you can +I a kqueue loop into the default loop: running the default loop +will then also service the kqueue loop to some extent. See the example in +the section about embed watchers for an example on how to achieve that. + =over 4 -=item $loop = new EV::loop [$flags] +=item $loop = new EV::Loop [$flags] -Create a new event loop as per the specified flags. Please refer to the -C function description in the libev documentation -(L) -for more info. +Create a new event loop as per the specified flags. Please refer to +the C function description in the libev documentation +(L, +or locally-installed as F manpage) for more info. The loop will automatically be destroyed when it is no longer referenced by any watcher and the loop object goes out of scope. -Using C is recommended, as only the default event loop -is protected by this module. +If you are not embedding the loop, then Using C +is recommended, as only the default event loop is protected by this +module. If you I embedding this loop in the default loop, this is not +necessary, as C automatically does the right thing on fork. =item $loop->loop_fork Must be called after a fork in the child, before entering or continuing the event loop. An alternative is to use C which calls -this fucntion automatically, at some performance loss (refer to the libev +this function automatically, at some performance loss (refer to the libev documentation). +=item $loop->loop_verify + +Calls C to make internal consistency checks (for debugging +libev) and abort the program if any data structures were found to be +corrupted. + =item $loop = EV::default_loop [$flags] -Return the default loop (which is a singleton object). +Return the default loop (which is a singleton object). Since this module +already creates the default loop with default flags, specifying flags here +will not have any effect unless you destroy the default loop first, which +isn't supported. So in short: don't do it, and if you break it, you get to +keep the pieces. =back @@ -170,15 +240,57 @@ =item $time = $loop->now Returns the time the last event loop iteration has been started. This -is the time that (relative) timers are based on, and refering to it is +is the time that (relative) timers are based on, and referring to it is usually faster then calling EV::time. +=item EV::now_update + +=item $loop->now_update + +Establishes the current time by querying the kernel, updating the time +returned by C in the progress. This is a costly operation and +is usually done automatically within C. + +This function is rarely useful, but when some event callback runs for a +very long time without entering the event loop, updating libev's idea of +the current time is a good idea. + +=item EV::suspend + +=item $loop->suspend + +=item EV::resume + +=item $loop->resume + +These two functions suspend and resume a loop, for use when the loop is +not used for a while and timeouts should not be processed. + +A typical use case would be an interactive program such as a game: When +the user presses C<^Z> to suspend the game and resumes it an hour later it +would be best to handle timeouts as if no time had actually passed while +the program was suspended. This can be achieved by calling C +in your C handler, sending yourself a C and calling +C directly afterwards to resume timer processing. + +Effectively, all C watchers will be delayed by the time spend +between C and C, and all C watchers +will be rescheduled (that is, they will lose any events that would have +occured while suspended). + +After calling C you B call I function on the given +loop other than C, and you B call C +without a previous call to C. + +Calling C/C has the side effect of updating the event +loop time (see C). + =item $backend = EV::backend =item $backend = $loop->backend -Returns an integer describing the backend used by libev (EV::METHOD_SELECT -or EV::METHOD_EPOLL). +Returns an integer describing the backend used by libev (EV::BACKEND_SELECT +or EV::BACKEND_EPOLL). =item EV::loop [$flags] @@ -208,7 +320,7 @@ =item $count = $loop->loop_count Return the number of times the event loop has polled for new -events. Sometiems useful as a generation counter. +events. Sometimes useful as a generation counter. =item EV::once $fh_or_undef, $events, $timeout, $cb->($revents) @@ -229,7 +341,7 @@ When an error occurs or either the timeout or I/O watcher triggers, then the callback will be called with the received event set (in general you can expect it to be a combination of C, C, -C and C). +C and C). EV::once doesn't return anything: the watchers stay active till either of them triggers, then they will be stopped and freed, and the callback @@ -258,8 +370,20 @@ These advanced functions set the minimum block interval when polling for I/O events and the minimum wait interval for timer events. See the libev documentation at -L for -a more detailed discussion. +L +(locally installed as F) for a more detailed discussion. + +=item $count = EV::pending_count + +=item $count = $loop->pending_count + +Returns the number of currently pending watchers. + +=item EV::invoke_pending + +=item $loop->invoke_pending + +Invoke all currently pending watchers. =back @@ -270,10 +394,10 @@ event. For instance, if you want to wait for STDIN to become readable, you would create an EV::io watcher for that: - my $watcher = EV::io *STDIN, EV::READ, sub { - my ($watcher, $revents) = @_; - warn "yeah, STDIN should now be readable without blocking!\n" - }; + my $watcher = EV::io *STDIN, EV::READ, sub { + my ($watcher, $revents) = @_; + warn "yeah, STDIN should now be readable without blocking!\n" + }; All watchers can be active (waiting for events) or inactive (paused). Only active watchers will have their callbacks invoked. All callbacks will be @@ -282,10 +406,9 @@ Each watcher type has its associated bit in revents, so you can use the same callback for multiple watchers. The event mask is named after the -type, i..e. EV::child sets EV::CHILD, EV::prepare sets EV::PREPARE, +type, i.e. EV::child sets EV::CHILD, EV::prepare sets EV::PREPARE, EV::periodic sets EV::PERIODIC and so on, with the exception of I/O events -(which can set both EV::READ and EV::WRITE bits), and EV::timer (which -uses EV::TIMEOUT). +(which can set both EV::READ and EV::WRITE bits). In the rare case where one wants to create a watcher but not start it at the same time, each constructor has a variant with a trailing C<_ns> in @@ -374,7 +497,7 @@ Normally, C will return when there are no active watchers (which is a "deadlock" because no progress can be made anymore). This is -convinient because it allows you to start your watchers (and your jobs), +convenient because it allows you to start your watchers (and your jobs), call C once and when it returns you know that all your jobs are finished (or they forgot to register some watchers for their task :). @@ -388,7 +511,7 @@ In this case you can clear the keepalive status, which means that even though your watcher is active, it won't keep C from returning. -The initial value for keepalive is true (enabled), and you cna change it +The initial value for keepalive is true (enabled), and you can change it any time. Example: Register an I/O watcher for some UDP socket but do not keep the @@ -396,7 +519,7 @@ my $udp_socket = ... my $udp_watcher = EV::io $udp_socket, EV::READ, sub { ... }; - $1000udp_watcher->keepalive (0); + $udp_watcher->keepalive (0); =item $loop = $w->loop @@ -535,7 +658,7 @@ at January 1st 2011 then it will run when the system time reaches or surpasses this time. -=item * non-repeating interval timer ($interval > 0, $reschedule_cb = 0) +=item * repeating interval timer ($interval > 0, $reschedule_cb = 0) In this mode the watcher will always be scheduled to time out at the next C<$at + N * $interval> time (for some integer N) and then repeat, @@ -563,13 +686,14 @@ time as second argument. I. If you need to stop it, return 1e30 and stop it -afterwards. +watcher, ever, and MUST NOT call any event loop functions or methods>. If +you need to stop it, return 1e30 and stop it afterwards. You may create +and start a C watcher for this task. It must return the next time to trigger, based on the passed time value -(that is, the lowest time value larger than to the second argument). It -will usually be called just before the callback will be triggered, but -might be called at other times, too. +(that is, the lowest time value larger than or equal to to the second +argument). It will usually be called just before the callback will be +triggered, but might be called at other times, too. This can be used to create very complex timers, such as a timer that triggers on each midnight, local time (actually 24 hours after the last @@ -615,9 +739,17 @@ =item $w = EV::signal_ns $signal, $callback +=item $w = $loop->signal ($signal, $callback) + +=item $w = $loop->signal_ns ($signal, $callback) + Call the callback when $signal is received (the signal can be specified by number or by name, just as with C or C<%SIG>). +Only one event loop can grab a given signal - attempting to grab the same +signal from two EV loops will crash the program immediately or cause data +corruption. + EV will grab the signal for the process (the kernel only allows one component to receive a signal at a time) when you start a signal watcher, and removes it again when you stop it. Perl does the same when you @@ -646,16 +778,18 @@ =over 4 -=item $w = EV::child $pid, $callback +=item $w = EV::child $pid, $trace, $callback -=item $w = EV::child_ns $pid, $callback +=item $w = EV::child_ns $pid, $trace, $callback -=item $w = $loop->child ($pid, $callback) +=item $w = $loop->child ($pid, $trace, $callback) -=item $w = $loop->child_ns ($pid, $callback) +=item $w = $loop->child_ns ($pid, $trace, $callback) -Call the callback when a status change for pid C<$pid> (or any pid if -C<$pid> is 0) has been received. More precisely: when the process receives +Call the callback when a status change for pid C<$pid> (or any pid +if C<$pid> is 0) has been received (a status change happens when the +process terminates or is killed, or, when trace is true, additionally when +it is stopped or continued). More precisely: when the process receives a C, EV will fetch the outstanding exit/wait status for all changed/zombie children and call the callback. @@ -672,15 +806,13 @@ The C variant doesn't start (activate) the newly created watcher. -=item $w->set ($pid) +=item $w->set ($pid, $trace) Reconfigures the watcher, see the constructor above for details. Can be called at any time. =item $current_pid = $w->pid -=item $old_pid = $w->pid ($new_pid) - Returns the previously set process id and optionally set a new one. =item $exit_status = $w->rstatus @@ -851,7 +983,7 @@ Call the callback just after the process wakes up again (after it has gathered events), but before any other callbacks have been invoked. -This is used to integrate other event-based software into the EV +This can be used to integrate other event-based software into the EV mainloop: You register a prepare callback and in there, you create io and timer watchers as required by the other software. Here is a real-world example of integrating Net::SNMP (with some details left out): @@ -891,11 +1023,21 @@ }; The callbacks of the created watchers will not be called as the watchers -are destroyed before this cna happen (remember EV::check gets called +are destroyed before this can happen (remember EV::check gets called first). The C variant doesn't start (activate) the newly created watcher. +=item EV::CHECK constant issues + +Like all other watcher types, there is a bitmask constant for use in +C<$revents> and other places. The C is special as it has +the same name as the C sub called by Perl. This doesn't cause +big issues on newer perls (beginning with 5.8.9), but it means thatthe +constant must be I, i.e. runtime calls will not work. That means +that as long as you always C and then C you are on the +safe side. + =back @@ -932,44 +1074,66 @@ See the libev documentation at L -for more details. +(locally installed as F) for more details. In short, this watcher is most useful on BSD systems without working kqueue to still be able to handle a large number of sockets: - my $socket_loop; - - # check wether we use SELECT or POLL _and_ KQUEUE is supported - if ( - (EV::backend & (EV::BACKEND_POLL | EV::BACKEND_SELECT)) - && (EV::supported_backends & EV::embeddable_backends & EV::BACKEND_KQUEUE) - ) { - # use kqueue for sockets - $socket_loop = new EV::Loop EV::BACKEND_KQUEUE | EV::FLAG_NOENV; - } - - # use the default loop otherwise - $socket_loop ||= EV::default_loop; + my $socket_loop; + + # check wether we use SELECT or POLL _and_ KQUEUE is supported + if ( + (EV::backend & (EV::BACKEND_POLL | EV::BACKEND_SELECT)) + && (EV::supported_backends & EV::embeddable_backends & EV::BACKEND_KQUEUE) + ) { + # use kqueue for sockets + $socket_loop = new EV::Loop EV::BACKEND_KQUEUE | EV::FLAG_NOENV; + } + + # use the default loop otherwise + $socket_loop ||= EV::default_loop; =over 4 -=item $w = EV::embed $otherloop, $callback +=item $w = EV::embed $otherloop[, $callback] -=item $w = EV::embed_ns $otherloop, $callback +=item $w = EV::embed_ns $otherloop[, $callback] -=item $w = $loop->embed ($otherloop, $callback) +=item $w = $loop->embed ($otherloop[, $callback]) -=item $w = $loop->embed_ns ($otherloop, $callback) +=item $w = $loop->embed_ns ($otherloop[, $callback]) Call the callback when the embedded event loop (C<$otherloop>) has any -I/O activity. The C<$callback> should alwas be specified as C in -this version of EV, which means the embedded event loop will be managed -automatically. +I/O activity. The C<$callback> is optional: if it is missing, then the +embedded event loop will be managed automatically (which is recommended), +otherwise you have to invoke C yourself. The C variant doesn't start (activate) the newly created watcher. =back +=head3 ASYNC WATCHERS - how to wake up another event loop + +Async watchers are provided by EV, but have little use in perl directly, +as perl neither supports threads running in parallel nor direct access to +signal handlers or other contexts where they could be of value. + +It is, however, possible to use them from the XS level. + +Please see the libev documentation for further details. + +=over 4 + +=item $w = EV::async $callback + +=item $w = EV::async_ns $callback + +=item $w->send + +=item $bool = $w->async_pending + +=back + =head1 PERL SIGNALS @@ -990,11 +1154,11 @@ This ensures that perl gets into control for a short time to handle any pending signals, and also ensures (slightly) slower overall operation. -=head1 THREADS +=head1 ITHREADS -Threads are not supported by this module in any way. Perl pseudo-threads -is evil stuff and must die. As soon as Perl gains real threads I will work -on thread support for it. +Ithreads are not supported by this module in any way. Perl pseudo-threads +is evil stuff and must die. Real threads as provided by Coro are fully +supported (and enhanced support is available via L). =head1 FORK @@ -1028,12 +1192,13 @@ L (asynchronous DNS), L (makes Glib/Gtk2 use EV as event loop), L (embed Glib into EV), L (efficient -coroutines with EV), L (asynchronous SNMP). +coroutines with EV), L (asynchronous SNMP), L for +event-loop agnostic and portable event driven programming. =head1 AUTHOR - Marc Lehmann - http://home.schmorp.de/ + Marc Lehmann + http://home.schmorp.de/ =cut