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

# User Rev Content
1 root 1.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 root 1.4 modules, namely asynchronous interruptions (think "UNIX signals", which
13 root 1.1 are very similar).
14    
15 root 1.8 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 root 1.1
22     This module implements asynchronous notifications that enable you to
23 root 1.8 signal running perl code from another thread, asynchronously, and
24     sometimes even without using a single syscall.
25 root 1.1
26 root 1.8 =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 root 1.2
78     You can signal the C<Async::Interrupt> object either by calling it's C<<
79 root 1.8 ->signal >> method, or, more commonly, by calling a C function. There is
80     also the built-in (POSIX) signal source.
81 root 1.2
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 root 1.8 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 root 1.2
93 root 1.1 =over 4
94    
95     =cut
96    
97     package Async::Interrupt;
98    
99 root 1.2 no warnings;
100    
101 root 1.1 BEGIN {
102 root 1.9 $VERSION = '0.041';
103 root 1.1
104     require XSLoader;
105     XSLoader::load Async::Interrupt::, $VERSION;
106     }
107    
108 root 1.2 our $DIED = sub { warn "$@" };
109    
110 root 1.1 =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 root 1.2 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 root 1.1
133 root 1.2 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 root 1.1
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 root 1.2 void c_func (pTHX_ void *c_arg, int value);
146 root 1.1
147 root 1.2 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 root 1.1
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 root 1.4 might use (the exception is C<errno>, which is saved and restored by
154 root 1.2 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 root 1.4 which case the requirements set out for C<cb> apply as well).
157 root 1.1
158 root 1.6 =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 root 1.2 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
168 root 1.1
169 root 1.2 Specifies two file descriptors (or file handles) that should be signalled
170 root 1.1 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 root 1.2 are written. It is required that the file handles are both in nonblocking
174     mode.
175 root 1.1
176 root 1.6 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 root 1.1
182 root 1.2 The object will keep a reference to the file handles.
183 root 1.1
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 root 1.6 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class
195 root 1.1 }
196    
197 root 1.2 =item ($signal_func, $signal_arg) = $async->signal_func
198 root 1.1
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 root 1.2 The function is safe to call from within signal and thread contexts, at
210 root 1.1 any time. The specified C<value> is passed to both C and Perl callback.
211    
212 root 1.2 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
213     portable).
214    
215 root 1.1 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 root 1.2 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 root 1.1
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 root 1.2 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 root 1.3 =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 root 1.4 Note that there must be exactly one call of C<unblock> for every previous
239 root 1.3 call to C<block> (i.e. calls can nest).
240    
241 root 1.4 Since ensuring this in the presence of exceptions and threads is
242 root 1.3 usually more difficult than you imagine, I recommend using C<<
243     $async->scoped_block >> instead.
244 root 1.2
245 root 1.3 =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 root 1.2
253 root 1.6 =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 root 1.1 =cut
267    
268     1;
269    
270     =back
271    
272 root 1.2 =head1 EXAMPLE
273    
274 root 1.8 There really should be a complete C/XS example. Bug me about it. Better
275     yet, create one.
276 root 1.2
277     =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
278    
279 root 1.8 This module works by "hijacking" SIGKILL, which is guaranteed to always
280     exist, but also cannot be caught, so is always available.
281 root 1.2
282 root 1.8 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 root 1.2
292 root 1.1 =head1 AUTHOR
293    
294     Marc Lehmann <schmorp@schmorp.de>
295     http://home.schmorp.de/
296    
297     =cut
298