=head1 NAME EV::Loop::Async - run an EV event loop asynchronously =head1 SYNOPSIS use EV::Loop::Async; my $loop = EV::Loop::Async::default; my $timer; my $flag; { $loop->scope_lock; # lock the loop structures $timer = $loop->timer (5, 1, sub { $flag = 1 }); $loop->nudge; # tell loop to take note of the timer } 1 while $flag; # $flag will be set asynchronously { $loop->interrupt->scope_block; # critical section, no watcher callback interruptions } # stop timer again { $loop->scope_lock; # lock the loop structures $timer->stop; # no need to nudge } =head1 DESCRIPTION This module implements a rather specialised event loop - it takes a normal L event loop and runs it in a separate thread. That means it will poll for events even while your foreground Perl interpreter is busy (you don't need to have perls pseudo-threads enabled for this either). Whenever the event loop detecs new events, it will interrupt perl and ask it to invoke all the pending watcher callbacks. This invocation will be "synchronous" (in the perl thread), but it can happen at any time. See the documentation for L for details on when and how your perl program can be interrupted (and how to avoid it), and how to integrate background event loops into foreground ones. =head1 FAQ =head1 FUNCTIONS, METHODS AND VARIABLES OF THIS MODULE =over 4 =cut package EV::Loop::Async; use common::sense; use EV (); use Async::Interrupt (); use base 'EV::Loop'; BEGIN { our $VERSION = '0.02'; require XSLoader; XSLoader::load ("EV::Loop::Async", $VERSION); } =item $loop = EV::Loop::Async::default Return the default loop, usable by all programs. The default loop will be created on the first call to C by calling X, and should be used by all programs unless they have special requirements. The associated L object is stored in C<$EV::Loop::Async::AI>, and can be used to lock critical sections etc. =cut our ($LOOP, $INTERRUPT); sub default() { $LOOP || do { $LOOP = new EV::Loop::Async; $INTERRUPT = $LOOP->interrupt; $LOOP } } =item $EV::Loop::Async::LOOP The default async loop, available after the first call to C. =item $EV::Loop::Async::INTERRUPT The default loop's L object, for easy access. Example: create a section of code where no callback invocations will interrupt: { $EV::Loop::Async::INTERRUPT->scope_block; # no default loop callbacks will be executed here. # the loop will not be locked, however. } =item $loop = new EV::Loop::Async $flags, [Async-Interrupt-Arguments...] This constructor: =over 4 =item 1. creates a new C (similar C). =item 2. creates a new L object and attaches itself to it. =item 3. creates a new background thread. =item 4. runs C<< $loop->run >> in that thread. =back The resulting loop will be running and unlocked when it is returned. =cut sub new { my ($class, $flags, @asy) = @_; my $self = bless $class->SUPER::new ($flags), $class; my ($c_func, $c_arg) = _c_func $self; my $asy = new Async::Interrupt @asy, c_cb => [$c_func, $c_arg]; $self->_attach ($asy, $asy->signal_func); $self } =item $loop->nudge Wake up the asynchronous loop. This is useful after registering a new watcher, to ensure that the background event loop integrates the new watcher(s) (which only happens when it iterates, which you can force by calling this method). Without calling this method, the event loop I takes notice of new watchers, bit when this happens is not wlel-defined (can be instantaneous, or take a few hours). No locking is required. Example: lock the loop, create a timer, nudge the loop so it takes notice of the new timer, then evily busy-wait till the timer fires. my $timer; my $flag; { $loop->scope_lock; $timer = $loop->timer (1, 0, sub { $flag = 1 }); $loop->nudge; } 1 until $flag; =item $loop->lock =item $loop->unlock Lock/unlock the loop data structures. Since the event loop runs in a separate thread, you have to lock the loop data structures before accessing them in any way. Since I was lazy, you have to do this manually. You must lock under the same conditions as you would have to lock the underlying C library, e.g. when starting or stopping watchers (but not when creating or destroying them, but note that create and destroy often starts and stops for you, in which case you have to lock). When in doubt, lock. See also the next method, C<< $loop->scope_lock >> for a more failsafe way to lock parts of your code. Note that there must be exactly one call of "unblock" for every previous call to "block" (i.e. calls can nest). =item $loop->scope_lock Calls C immediately, and C automatically whent he current scope is left. =back =head1 SEE ALSO L, L. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ =cut 1