ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
Revision: 1.9
Committed: Sun Jul 12 16:33:26 2009 UTC (14 years, 11 months ago) by root
Branch: MAIN
CVS Tags: rel-0_041
Changes since 1.8: +1 -1 lines
Log Message:
0.041

File Contents

# Content
1 =head1 NAME
2
3 Async::Interrupt - allow C/XS libraries to interrupt perl asynchronously
4
5 =head1 SYNOPSIS
6
7 use Async::Interrupt;
8
9 =head1 DESCRIPTION
10
11 This module implements a single feature only of interest to advanced perl
12 modules, namely asynchronous interruptions (think "UNIX signals", which
13 are very similar).
14
15 Sometimes, modules wish to run code asynchronously (in another thread,
16 or from a signal handler), and then signal the perl interpreter on
17 certain events. One common way is to write some data to a pipe and use an
18 event handling toolkit to watch for I/O events. Another way is to send
19 a signal. Those methods are slow, and in the case of a pipe, also not
20 asynchronous - it won't interrupt a running perl interpreter.
21
22 This module implements asynchronous notifications that enable you to
23 signal running perl code from another thread, asynchronously, and
24 sometimes even without using a single syscall.
25
26 =head2 USAGE SCENARIOS
27
28 =over 4
29
30 =item Race-free signal handling
31
32 There seems to be no way to do race-free signal handling in perl: to
33 catch a signal, you have to execute Perl code, and between entering the
34 interpreter C<select> function (or other blocking functions) and executing
35 the select syscall is a small but relevant timespan during which signals
36 will be queued, but perl signal handlers will not be executed and the
37 blocking syscall will not be interrupted.
38
39 You can use this module to bind a signal to a callback while at the same
40 time activating an event pipe that you can C<select> on, fixing the race
41 completely.
42
43 This can be used to implement the signal hadling in event loops,
44 e.g. L<AnyEvent>, L<POE>, L<IO::Async::Loop> and so on.
45
46 =item Background threads want speedy reporting
47
48 Assume you want very exact timing, and you can spare an extra cpu core
49 for that. Then you can run an extra thread that signals your perl
50 interpreter. This means you can get a very exact timing source while your
51 perl code is number crunching, without even using a syscall to communicate
52 between your threads.
53
54 For example the deliantra game server uses a variant of this technique
55 to interrupt background processes regularly to send map updates to game
56 clients.
57
58 L<IO::AIO> and L<BDB> could also use this to speed up result reporting.
59
60 =item Speedy event loop invocation
61
62 One could use this module e.g. in L<Coro> to interrupt a running coro-thread
63 and cause it to enter the event loop.
64
65 Or one could bind to C<SIGIO> and tell some important sockets to send this
66 signal, causing the event loop to be entered to reduce network latency.
67
68 =back
69
70 =head2 HOW TO USE
71
72 You can use this module by creating an C<Async::Interrupt> object for each
73 such event source. This object stores a perl and/or a C-level callback
74 that is invoked when the C<Async::Interrupt> object gets signalled. It is
75 executed at the next time the perl interpreter is running (i.e. it will
76 interrupt a computation, but not an XS function or a syscall).
77
78 You can signal the C<Async::Interrupt> object either by calling it's C<<
79 ->signal >> method, or, more commonly, by calling a C function. There is
80 also the built-in (POSIX) signal source.
81
82 The C<< ->signal_func >> returns the address of the C function that is to
83 be called (plus an argument to be used during the call). The signalling
84 function also takes an integer argument in the range SIG_ATOMIC_MIN to
85 SIG_ATOMIC_MAX (guaranteed to allow at least 0..127).
86
87 Since this kind of interruption is fast, but can only interrupt a
88 I<running> interpreter, there is optional support for signalling a pipe
89 - that means you can also wait for the pipe to become readable (e.g. via
90 L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a C<read>
91 and C<write> syscall.
92
93 =over 4
94
95 =cut
96
97 package Async::Interrupt;
98
99 no warnings;
100
101 BEGIN {
102 $VERSION = '0.041';
103
104 require XSLoader;
105 XSLoader::load Async::Interrupt::, $VERSION;
106 }
107
108 our $DIED = sub { warn "$@" };
109
110 =item $async = new Async::Interrupt key => value...
111
112 Creates a new Async::Interrupt object. You may only use async
113 notifications on this object while it exists, so you need to keep a
114 reference to it at all times while it is used.
115
116 Optional constructor arguments include (normally you would specify at
117 least one of C<cb> or C<c_cb>).
118
119 =over 4
120
121 =item cb => $coderef->($value)
122
123 Registers a perl callback to be invoked whenever the async interrupt is
124 signalled.
125
126 Note that, since this callback can be invoked at basically any time, it
127 must not modify any well-known global variables such as C<$/> without
128 restoring them again before returning.
129
130 The exceptions are C<$!> and C<$@>, which are saved and restored by
131 Async::Interrupt.
132
133 If the callback should throw an exception, then it will be caught,
134 and C<$Async::Interrupt::DIED> will be called with C<$@> containing
135 the exception. The default will simply C<warn> about the message and
136 continue.
137
138 =item c_cb => [$c_func, $c_arg]
139
140 Registers a C callback the be invoked whenever the async interrupt is
141 signalled.
142
143 The C callback must have the following prototype:
144
145 void c_func (pTHX_ void *c_arg, int value);
146
147 Both C<$c_func> and C<$c_arg> must be specified as integers/IVs, and
148 C<$value> is the C<value> passed to some earlier call to either C<$signal>
149 or the C<signal_func> function.
150
151 Note that, because the callback can be invoked at almost any time, you
152 have to be careful at saving and restoring global variables that Perl
153 might use (the exception is C<errno>, which is saved and restored by
154 Async::Interrupt). The callback itself runs as part of the perl context,
155 so you can call any perl functions and modify any perl data structures (in
156 which case the requirements set out for C<cb> apply as well).
157
158 =item signal => $signame_or_value
159
160 When this parameter is specified, then the Async::Interrupt will hook the
161 given signal, that is, it will effectively call C<< ->signal (0) >> each time
162 the given signal is caught by the process.
163
164 Only one async can hook a given signal, and the signal will be restored to
165 defaults when the Async::Interrupt object gets destroyed.
166
167 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
168
169 Specifies two file descriptors (or file handles) that should be signalled
170 whenever the async interrupt is signalled. This means a single octet will
171 be written to it, and before the callback is being invoked, it will be
172 read again. Due to races, it is unlikely but possible that multiple octets
173 are written. It is required that the file handles are both in nonblocking
174 mode.
175
176 You can get a portable pipe and set non-blocking mode portably by using
177 e.g. L<AnyEvent::Util> from the L<AnyEvent> distribution.
178
179 It is also possible to pass in a linux eventfd as both read and write
180 handle (which is faster than a pipe).
181
182 The object will keep a reference to the file handles.
183
184 This can be used to ensure that async notifications will interrupt event
185 frameworks as well.
186
187 =back
188
189 =cut
190
191 sub new {
192 my ($class, %arg) = @_;
193
194 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class
195 }
196
197 =item ($signal_func, $signal_arg) = $async->signal_func
198
199 Returns the address of a function to call asynchronously. The function has
200 the following prototype and needs to be passed the specified C<$c_arg>,
201 which is a C<void *> cast to C<IV>:
202
203 void (*signal_func) (void *signal_arg, int value)
204
205 An example call would look like:
206
207 signal_func (signal_arg, 0);
208
209 The function is safe to call from within signal and thread contexts, at
210 any time. The specified C<value> is passed to both C and Perl callback.
211
212 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
213 portable).
214
215 If the function is called while the Async::Interrupt object is already
216 signaled but before the callbacks are being executed, then the stored
217 C<value> is either the old or the new one. Due to the asynchronous
218 nature of the code, the C<value> can even be passed to two consecutive
219 invocations of the callback.
220
221 =item $async->signal ($value=0)
222
223 This signals the given async object from Perl code. Semi-obviously, this
224 will instantly trigger the callback invocation.
225
226 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
227 portable).
228
229 =item $async->block
230
231 =item $async->unblock
232
233 Sometimes you need a "critical section" of code that will not be
234 interrupted by an Async::Interrupt. This can be implemented by calling C<<
235 $async->block >> before the critical section, and C<< $async->unblock >>
236 afterwards.
237
238 Note that there must be exactly one call of C<unblock> for every previous
239 call to C<block> (i.e. calls can nest).
240
241 Since ensuring this in the presence of exceptions and threads is
242 usually more difficult than you imagine, I recommend using C<<
243 $async->scoped_block >> instead.
244
245 =item $async->scope_block
246
247 This call C<< $async->block >> and installs a handler that is called when
248 the current scope is exited (via an exception, by canceling the Coro
249 thread, by calling last/goto etc.).
250
251 This is the recommended (and fastest) way to implement critical sections.
252
253 =item $async->pipe_enable
254
255 =item $async->pipe_disable
256
257 Enable/disable signalling the pipe when the interrupt occurs (default is
258 enabled). Writing to a pipe is relatively expensive, so it can be disabled
259 when you know you are not waiting for it (for example, with L<EV> you
260 could disable the pipe in a check watcher, and enable it in a prepare
261 watcher).
262
263 Note that when C<fd_disable> is in effect, no attempt to read from the
264 pipe will be done.
265
266 =cut
267
268 1;
269
270 =back
271
272 =head1 EXAMPLE
273
274 There really should be a complete C/XS example. Bug me about it. Better
275 yet, create one.
276
277 =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
278
279 This module works by "hijacking" SIGKILL, which is guaranteed to always
280 exist, but also cannot be caught, so is always available.
281
282 Basically, this module fakes the occurance of a SIGKILL signal and
283 then intercepts the interpreter handling it. This makes normal signal
284 handling slower (probably unmeasurably, though), but has the advantage
285 of not requiring a special runops function, nor slowing down normal perl
286 execution a bit.
287
288 It assumes that C<sig_atomic_t> and C<int> are both async-safe to modify
289 (C<sig_atomic_> is used by this module, and perl itself uses C<int>, so we
290 can assume that this is quite portable, at least w.r.t. signals).
291
292 =head1 AUTHOR
293
294 Marc Lehmann <schmorp@schmorp.de>
295 http://home.schmorp.de/
296
297 =cut
298