ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Loop-Async/Async.pm
Revision: 1.3
Committed: Tue Jul 14 15:09:44 2009 UTC (14 years, 10 months ago) by root
Branch: MAIN
Changes since 1.2: +32 -7 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 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     our $VERSION = '0.02';
93    
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     =item $loop = new EV::Loop::Async $flags, [Async-Interrupt-Arguments...]
139 root 1.1
140     This constructor:
141    
142     =over 4
143    
144     =item 1. creates a new C<EV::Loop> (similar C<new EV::Loop>).
145    
146     =item 2. creates a new L<Async::Interrupt> object and attaches itself to it.
147    
148 root 1.2 =item 3. creates a new background thread.
149 root 1.1
150 root 1.2 =item 4. runs C<< $loop->run >> in that thread.
151 root 1.1
152 root 1.2 =back
153 root 1.1
154 root 1.2 The resulting loop will be running and unlocked when it is returned.
155 root 1.1
156     =cut
157    
158     sub new {
159     my ($class, $flags, @asy) = @_;
160    
161     my $self = bless $class->SUPER::new ($flags), $class;
162     my ($c_func, $c_arg) = _c_func $self;
163     my $asy = new Async::Interrupt @asy, c_cb => [$c_func, $c_arg];
164     $self->_attach ($asy, $asy->signal_func);
165    
166     $self
167     }
168    
169 root 1.3 =item $loop->notify
170 root 1.1
171     Wake up the asynchronous loop. This is useful after registering a new
172     watcher, to ensure that the background event loop integrates the new
173     watcher(s) (which only happens when it iterates, which you can force by
174     calling this method).
175    
176     Without calling this method, the event loop I<eventually> takes notice
177 root 1.3 of new watchers, bit when this happens is not well-defined (can be
178 root 1.1 instantaneous, or take a few hours).
179    
180     No locking is required.
181    
182     Example: lock the loop, create a timer, nudge the loop so it takes notice
183     of the new timer, then evily busy-wait till the timer fires.
184    
185     my $timer;
186     my $flag;
187    
188     {
189     $loop->scope_lock;
190     $timer = $loop->timer (1, 0, sub { $flag = 1 });
191 root 1.3 $loop->notify;
192 root 1.1 }
193    
194     1 until $flag;
195    
196 root 1.2 =item $loop->lock
197    
198     =item $loop->unlock
199    
200     Lock/unlock the loop data structures. Since the event loop runs in
201     a separate thread, you have to lock the loop data structures before
202     accessing them in any way. Since I was lazy, you have to do this manually.
203    
204     You must lock under the same conditions as you would have to lock the
205     underlying C library, e.g. when starting or stopping watchers (but not
206     when creating or destroying them, but note that create and destroy often
207     starts and stops for you, in which case you have to lock).
208    
209     When in doubt, lock.
210    
211     See also the next method, C<< $loop->scope_lock >> for a more failsafe way
212     to lock parts of your code.
213    
214     Note that there must be exactly one call of "unblock" for every previous
215     call to "block" (i.e. calls can nest).
216    
217     =item $loop->scope_lock
218    
219     Calls C<lock> immediately, and C<unlock> automatically whent he current
220     scope is left.
221    
222     =back
223    
224 root 1.1 =head1 SEE ALSO
225    
226     L<EV>, L<Async::Interrupt>.
227    
228     =head1 AUTHOR
229    
230     Marc Lehmann <schmorp@schmorp.de>
231     http://home.schmorp.de/
232    
233     =cut
234    
235     1
236