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

# Content
1 =head1 NAME
2
3 EV::Loop::Async - run an EV event loop asynchronously
4
5 =head1 SYNOPSIS
6
7 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
34 =head1 DESCRIPTION
35
36 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
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 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 =cut
83
84 our ($LOOP, $INTERRUPT);
85
86 sub default() {
87 $LOOP || do {
88 $LOOP = new EV::Loop::Async;
89 $INTERRUPT = $LOOP->interrupt;
90
91 $LOOP
92 }
93 }
94
95 =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
104 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
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 =item 3. creates a new background thread.
124
125 =item 4. runs C<< $loop->run >> in that thread.
126
127 =back
128
129 The resulting loop will be running and unlocked when it is returned.
130
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 =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 =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