--- EV-Loop-Async/Async.pm 2009/07/14 02:59:55 1.1 +++ EV-Loop-Async/Async.pm 2009/07/14 13:24:34 1.2 @@ -4,11 +4,51 @@ =head1 SYNOPSIS - use EV::Loop::Async; + 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 -TODO. +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 @@ -36,21 +76,41 @@ 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, $ASYNC); +our ($LOOP, $INTERRUPT); sub default() { $LOOP || do { - $LOOP = new EV::Loop::Async; -# $ASYNC = $LOOP->async; + $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. -=item $loop = new EV::Loop $flags, [Async-Interrupt-Arguments...] +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: @@ -60,14 +120,14 @@ =item 2. creates a new L object and attaches itself to it. -=item 3. locks the loop (see below). - -=item 4. creates a new background thread. +=item 3. creates a new background thread. -=item 5. runs C<< $loop->run >> in that 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 { @@ -108,6 +168,34 @@ 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.