ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Loop-Async/Async.pm
Revision: 1.2
Committed: Tue Jul 14 13:24:34 2009 UTC (14 years, 10 months ago) by root
Branch: MAIN
Changes since 1.1: +98 -10 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     EV::Loop::Async - run an EV event loop asynchronously
4    
5     =head1 SYNOPSIS
6    
7 root 1.2 use EV::Loop::Async;
8    
9     my $loop = EV::Loop::Async::default;
10     my $timer;
11     my $flag;
12    
13     {
14     $loop->scope_lock; # lock the loop structures
15     $timer = $loop->timer (5, 1, sub { $flag = 1 });
16     $loop->nudge; # tell loop to take note of the timer
17     }
18    
19     1 while $flag; # $flag will be set asynchronously
20    
21     {
22     $loop->interrupt->scope_block;
23     # critical section, no watcher callback interruptions
24     }
25    
26     # stop timer again
27    
28     {
29     $loop->scope_lock; # lock the loop structures
30     $timer->stop;
31     # no need to nudge
32     }
33 root 1.1
34     =head1 DESCRIPTION
35    
36 root 1.2 This module implements a rather specialised event loop - it takes a normal
37     L<EV> event loop and runs it in a separate thread. That means it will poll
38     for events even while your foreground Perl interpreter is busy (you don't
39     need to have perls pseudo-threads enabled for this either).
40    
41     Whenever the event loop detecs new events, it will interrupt perl and ask
42     it to invoke all the pending watcher callbacks. This invocation will be
43     "synchronous" (in the perl thread), but it can happen at any time.
44    
45     See the documentation for L<Async::Interrupt> for details on when and how
46     your perl program can be interrupted (and how to avoid it), and how to
47     integrate background event loops into foreground ones.
48    
49     =head1 FAQ
50    
51     =head1 FUNCTIONS, METHODS AND VARIABLES OF THIS MODULE
52 root 1.1
53     =over 4
54    
55     =cut
56    
57     package EV::Loop::Async;
58    
59     use common::sense;
60    
61     use EV ();
62     use Async::Interrupt ();
63    
64     use base 'EV::Loop';
65    
66     BEGIN {
67     our $VERSION = '0.02';
68    
69     require XSLoader;
70     XSLoader::load ("EV::Loop::Async", $VERSION);
71     }
72    
73     =item $loop = EV::Loop::Async::default
74    
75     Return the default loop, usable by all programs. The default loop will be
76     created on the first call to C<default> by calling X<new EV::Loop>, and
77     should be used by all programs unless they have special requirements.
78    
79 root 1.2 The associated L<Async::Interrupt> object is stored in
80     C<$EV::Loop::Async::AI>, and can be used to lock critical sections etc.
81    
82 root 1.1 =cut
83    
84 root 1.2 our ($LOOP, $INTERRUPT);
85 root 1.1
86     sub default() {
87     $LOOP || do {
88 root 1.2 $LOOP = new EV::Loop::Async;
89     $INTERRUPT = $LOOP->interrupt;
90 root 1.1
91     $LOOP
92     }
93     }
94    
95 root 1.2 =item $EV::Loop::Async::LOOP
96    
97     The default async loop, available after the first call to
98     C<EV::Loop::Async::default>.
99    
100     =item $EV::Loop::Async::INTERRUPT
101    
102     The default loop's L<Async::Interrupt> object, for easy access.
103 root 1.1
104 root 1.2 Example: create a section of code where no callback invocations will
105     interrupt:
106    
107     {
108     $EV::Loop::Async::INTERRUPT->scope_block;
109     # no default loop callbacks will be executed here.
110     # the loop will not be locked, however.
111     }
112    
113     =item $loop = new EV::Loop::Async $flags, [Async-Interrupt-Arguments...]
114 root 1.1
115     This constructor:
116    
117     =over 4
118    
119     =item 1. creates a new C<EV::Loop> (similar C<new EV::Loop>).
120    
121     =item 2. creates a new L<Async::Interrupt> object and attaches itself to it.
122    
123 root 1.2 =item 3. creates a new background thread.
124 root 1.1
125 root 1.2 =item 4. runs C<< $loop->run >> in that thread.
126 root 1.1
127 root 1.2 =back
128 root 1.1
129 root 1.2 The resulting loop will be running and unlocked when it is returned.
130 root 1.1
131     =cut
132    
133     sub new {
134     my ($class, $flags, @asy) = @_;
135    
136     my $self = bless $class->SUPER::new ($flags), $class;
137     my ($c_func, $c_arg) = _c_func $self;
138     my $asy = new Async::Interrupt @asy, c_cb => [$c_func, $c_arg];
139     $self->_attach ($asy, $asy->signal_func);
140    
141     $self
142     }
143    
144     =item $loop->nudge
145    
146     Wake up the asynchronous loop. This is useful after registering a new
147     watcher, to ensure that the background event loop integrates the new
148     watcher(s) (which only happens when it iterates, which you can force by
149     calling this method).
150    
151     Without calling this method, the event loop I<eventually> takes notice
152     of new watchers, bit when this happens is not wlel-defined (can be
153     instantaneous, or take a few hours).
154    
155     No locking is required.
156    
157     Example: lock the loop, create a timer, nudge the loop so it takes notice
158     of the new timer, then evily busy-wait till the timer fires.
159    
160     my $timer;
161     my $flag;
162    
163     {
164     $loop->scope_lock;
165     $timer = $loop->timer (1, 0, sub { $flag = 1 });
166     $loop->nudge;
167     }
168    
169     1 until $flag;
170    
171 root 1.2 =item $loop->lock
172    
173     =item $loop->unlock
174    
175     Lock/unlock the loop data structures. Since the event loop runs in
176     a separate thread, you have to lock the loop data structures before
177     accessing them in any way. Since I was lazy, you have to do this manually.
178    
179     You must lock under the same conditions as you would have to lock the
180     underlying C library, e.g. when starting or stopping watchers (but not
181     when creating or destroying them, but note that create and destroy often
182     starts and stops for you, in which case you have to lock).
183    
184     When in doubt, lock.
185    
186     See also the next method, C<< $loop->scope_lock >> for a more failsafe way
187     to lock parts of your code.
188    
189     Note that there must be exactly one call of "unblock" for every previous
190     call to "block" (i.e. calls can nest).
191    
192     =item $loop->scope_lock
193    
194     Calls C<lock> immediately, and C<unlock> automatically whent he current
195     scope is left.
196    
197     =back
198    
199 root 1.1 =head1 SEE ALSO
200    
201     L<EV>, L<Async::Interrupt>.
202    
203     =head1 AUTHOR
204    
205     Marc Lehmann <schmorp@schmorp.de>
206     http://home.schmorp.de/
207    
208     =cut
209    
210     1
211