ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Loop-Async/Async.pm
Revision: 1.8
Committed: Mon Nov 1 22:26:53 2010 UTC (13 years, 6 months ago) by root
Branch: MAIN
Changes since 1.7: +1 -1 lines
Log Message:
1.0

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 root 1.3 # create a watcher, but make sure the loop is locked
14 root 1.2 {
15     $loop->scope_lock; # lock the loop structures
16     $timer = $loop->timer (5, 1, sub { $flag = 1 });
17 root 1.3 $loop->notify; # tell loop to take note of the timer
18 root 1.2 }
19    
20     1 while $flag; # $flag will be set asynchronously
21    
22 root 1.3 # implement a critical section, uninterrupted by any callbacks
23 root 1.2 {
24     $loop->interrupt->scope_block;
25     # critical section, no watcher callback interruptions
26     }
27    
28 root 1.3 # stop the timer watcher again - locking is required once more
29 root 1.2 {
30     $loop->scope_lock; # lock the loop structures
31     $timer->stop;
32 root 1.3 # no need to notify
33 root 1.2 }
34 root 1.1
35     =head1 DESCRIPTION
36    
37 root 1.2 This module implements a rather specialised event loop - it takes a normal
38     L<EV> event loop and runs it in a separate thread. That means it will poll
39     for events even while your foreground Perl interpreter is busy (you don't
40     need to have perls pseudo-threads enabled for this either).
41    
42     Whenever the event loop detecs new events, it will interrupt perl and ask
43     it to invoke all the pending watcher callbacks. This invocation will be
44     "synchronous" (in the perl thread), but it can happen at any time.
45    
46     See the documentation for L<Async::Interrupt> for details on when and how
47     your perl program can be interrupted (and how to avoid it), and how to
48     integrate background event loops into foreground ones.
49    
50     =head1 FAQ
51    
52 root 1.3 =over 4
53    
54     =item Why on earth...???
55    
56     Sometimes you need lower latency for specific events, but it's too heavy
57     to continuously poll for events. And perl already does this for you
58     anyways, so this module only uses this existing mechanism.
59    
60     =item When do I have to lock?
61    
62     When in doubt, lock. Do not start or stop a watcher, do not create a
63     watcher (unless with the C<_ns> methods) and do not DESTROY an active
64     watcher without locking either.
65    
66     Any other event loop modifications need to be done while locked as
67     well. So when in doubt, lock (best using C<scope_lock>).
68    
69     =item Why explicit locking?
70    
71     Because I was too lazy to wrap everything and there are probably only a
72     few people on this world using this module.
73    
74     =back
75    
76 root 1.2 =head1 FUNCTIONS, METHODS AND VARIABLES OF THIS MODULE
77 root 1.1
78     =over 4
79    
80     =cut
81    
82     package EV::Loop::Async;
83    
84     use common::sense;
85    
86     use EV ();
87     use Async::Interrupt ();
88    
89     use base 'EV::Loop';
90    
91     BEGIN {
92 root 1.8 our $VERSION = '1.0';
93 root 1.1
94     require XSLoader;
95     XSLoader::load ("EV::Loop::Async", $VERSION);
96     }
97    
98     =item $loop = EV::Loop::Async::default
99    
100     Return the default loop, usable by all programs. The default loop will be
101     created on the first call to C<default> by calling X<new EV::Loop>, and
102     should be used by all programs unless they have special requirements.
103    
104 root 1.2 The associated L<Async::Interrupt> object is stored in
105     C<$EV::Loop::Async::AI>, and can be used to lock critical sections etc.
106    
107 root 1.1 =cut
108    
109 root 1.2 our ($LOOP, $INTERRUPT);
110 root 1.1
111     sub default() {
112     $LOOP || do {
113 root 1.2 $LOOP = new EV::Loop::Async;
114     $INTERRUPT = $LOOP->interrupt;
115 root 1.1
116     $LOOP
117     }
118     }
119    
120 root 1.2 =item $EV::Loop::Async::LOOP
121    
122     The default async loop, available after the first call to
123     C<EV::Loop::Async::default>.
124    
125     =item $EV::Loop::Async::INTERRUPT
126    
127     The default loop's L<Async::Interrupt> object, for easy access.
128 root 1.1
129 root 1.2 Example: create a section of code where no callback invocations will
130     interrupt:
131    
132     {
133     $EV::Loop::Async::INTERRUPT->scope_block;
134     # no default loop callbacks will be executed here.
135     # the loop will not be locked, however.
136     }
137    
138 root 1.4 Example: embed the default EV::Async::Loop loop into the default L<EV>
139     loop (note that it could be any other event loop as well).
140    
141     my $async_w = EV::io
142     $EV::Loop::Async::LOOP->interrupt->pipe_fileno,
143     EV::READ,
144     sub { };
145    
146 root 1.2 =item $loop = new EV::Loop::Async $flags, [Async-Interrupt-Arguments...]
147 root 1.1
148     This constructor:
149    
150     =over 4
151    
152     =item 1. creates a new C<EV::Loop> (similar C<new EV::Loop>).
153    
154     =item 2. creates a new L<Async::Interrupt> object and attaches itself to it.
155    
156 root 1.2 =item 3. creates a new background thread.
157 root 1.1
158 root 1.2 =item 4. runs C<< $loop->run >> in that thread.
159 root 1.1
160 root 1.2 =back
161 root 1.1
162 root 1.2 The resulting loop will be running and unlocked when it is returned.
163 root 1.1
164 root 1.4 Example: create a new loop, block it's interrupt object and embed
165     it into the foreground L<AnyEvent> event loop. This basically runs the
166     C<EV::Loop::Async> loop in a synchronous way inside another loop.
167    
168     my $loop = new EV::Loop::Async 0;
169     my $async = $loop->interrupt;
170    
171     $async->block;
172    
173     my $async_w = AnyEvent->io (
174     fh => $async->pipe_fileno,
175     poll => "r",
176     cb => sub {
177     # temporarily unblock to handle events
178     $async->unblock;
179     $async->block;
180     },
181     );
182    
183 root 1.1 =cut
184    
185     sub new {
186     my ($class, $flags, @asy) = @_;
187    
188     my $self = bless $class->SUPER::new ($flags), $class;
189     my ($c_func, $c_arg) = _c_func $self;
190     my $asy = new Async::Interrupt @asy, c_cb => [$c_func, $c_arg];
191 root 1.7 _attach $self, $asy, $asy->signal_func;
192 root 1.1
193     $self
194     }
195    
196 root 1.3 =item $loop->notify
197 root 1.1
198     Wake up the asynchronous loop. This is useful after registering a new
199     watcher, to ensure that the background event loop integrates the new
200     watcher(s) (which only happens when it iterates, which you can force by
201     calling this method).
202    
203     Without calling this method, the event loop I<eventually> takes notice
204 root 1.3 of new watchers, bit when this happens is not well-defined (can be
205 root 1.1 instantaneous, or take a few hours).
206    
207     No locking is required.
208    
209     Example: lock the loop, create a timer, nudge the loop so it takes notice
210     of the new timer, then evily busy-wait till the timer fires.
211    
212     my $timer;
213     my $flag;
214    
215     {
216     $loop->scope_lock;
217     $timer = $loop->timer (1, 0, sub { $flag = 1 });
218 root 1.3 $loop->notify;
219 root 1.1 }
220    
221     1 until $flag;
222    
223 root 1.2 =item $loop->lock
224    
225     =item $loop->unlock
226    
227     Lock/unlock the loop data structures. Since the event loop runs in
228     a separate thread, you have to lock the loop data structures before
229     accessing them in any way. Since I was lazy, you have to do this manually.
230    
231     You must lock under the same conditions as you would have to lock the
232     underlying C library, e.g. when starting or stopping watchers (but not
233     when creating or destroying them, but note that create and destroy often
234     starts and stops for you, in which case you have to lock).
235    
236     When in doubt, lock.
237    
238     See also the next method, C<< $loop->scope_lock >> for a more failsafe way
239     to lock parts of your code.
240    
241     Note that there must be exactly one call of "unblock" for every previous
242     call to "block" (i.e. calls can nest).
243    
244     =item $loop->scope_lock
245    
246     Calls C<lock> immediately, and C<unlock> automatically whent he current
247     scope is left.
248    
249 root 1.4 =item $loop->set_max_foreground_loops ($max_loops)
250    
251     The background loop will immediately stop polling for new events after it
252     has collected at least one new event, regardless of how long it then takes
253     to actually handle them.
254    
255     When Perl finally handles the events, there could be many more ready
256     file descriptors. To improve latency and performance, you can ask
257     C<EV::Loop::Async> to loop an additional number of times in the foreground
258     after invoking the callbacks, effectively doing the polling in the
259     foreground.
260    
261 root 1.5 The default is C<0>, meaning that no foreground polling will be done. A
262 root 1.4 value of C<1> means that, after handling the pending events, it will call
263     C<< $loop->loop (EV::LOOP_NONBLOCK) >> and handle the resulting events, if
264     any. A value of C<2> means that this will be iterated twice.
265    
266     When a foreground event poll does not yield any new events, then no
267     further iterations will be made, so this is only a I<maximum> value of
268     additional loop runs.
269    
270 root 1.5 Take also note of the standard EV C<set_io_collect_interval>
271     functionality, which can achieve a similar, but different, effect - YMMV.
272    
273 root 1.2 =back
274    
275 root 1.1 =head1 SEE ALSO
276    
277     L<EV>, L<Async::Interrupt>.
278    
279     =head1 AUTHOR
280    
281     Marc Lehmann <schmorp@schmorp.de>
282     http://home.schmorp.de/
283    
284     =cut
285    
286     1
287