ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
Revision: 1.6
Committed: Sat Jul 11 22:16:50 2009 UTC (14 years, 10 months ago) by root
Branch: MAIN
Changes since 1.5: +28 -3 lines
Log Message:
*** empty log message ***

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     Sometimes, modules wish to run code asynchronously (in another thread),
16     and then signal the perl interpreter on certain events. One common way is
17     to write some data to a pipe and use an event handling toolkit to watch
18     for I/O events. Another way is to send a signal. Those methods are slow,
19     and in the case of a pipe, also not asynchronous - it won't interrupt a
20     running perl interpreter.
21    
22     This module implements asynchronous notifications that enable you to
23     signal running perl code form another thread, asynchronously, without
24     issuing syscalls.
25    
26 root 1.2 It works by creating an C<Async::Interrupt> object for each such use. This
27     object stores a perl and/or a C-level callback that is invoked when the
28     C<Async::Interrupt> object gets signalled. It is executed at the next time
29     the perl interpreter is running (i.e. it will interrupt a computation, but
30     not an XS function or a syscall).
31    
32     You can signal the C<Async::Interrupt> object either by calling it's C<<
33     ->signal >> method, or, more commonly, by calling a C function.
34    
35     The C<< ->signal_func >> returns the address of the C function that is to
36     be called (plus an argument to be used during the call). The signalling
37     function also takes an integer argument in the range SIG_ATOMIC_MIN to
38     SIG_ATOMIC_MAX (guaranteed to allow at least 0..127).
39    
40     Since this kind of interruption is fast, but can only interrupt a
41     I<running> interpreter, there is optional support for also signalling a
42 root 1.4 pipe - that means you can also wait for the pipe to become readable (e.g.
43     via L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a
44     C<read> and C<write> syscall.
45 root 1.2
46 root 1.1 =over 4
47    
48     =cut
49    
50     package Async::Interrupt;
51    
52 root 1.2 no warnings;
53    
54 root 1.1 BEGIN {
55 root 1.5 $VERSION = '0.03';
56 root 1.1
57     require XSLoader;
58     XSLoader::load Async::Interrupt::, $VERSION;
59     }
60    
61 root 1.2 our $DIED = sub { warn "$@" };
62    
63 root 1.1 =item $async = new Async::Interrupt key => value...
64    
65     Creates a new Async::Interrupt object. You may only use async
66     notifications on this object while it exists, so you need to keep a
67     reference to it at all times while it is used.
68    
69     Optional constructor arguments include (normally you would specify at
70     least one of C<cb> or C<c_cb>).
71    
72     =over 4
73    
74     =item cb => $coderef->($value)
75    
76     Registers a perl callback to be invoked whenever the async interrupt is
77     signalled.
78    
79     Note that, since this callback can be invoked at basically any time, it
80 root 1.2 must not modify any well-known global variables such as C<$/> without
81     restoring them again before returning.
82    
83     The exceptions are C<$!> and C<$@>, which are saved and restored by
84     Async::Interrupt.
85 root 1.1
86 root 1.2 If the callback should throw an exception, then it will be caught,
87     and C<$Async::Interrupt::DIED> will be called with C<$@> containing
88     the exception. The default will simply C<warn> about the message and
89     continue.
90    
91     =item c_cb => [$c_func, $c_arg]
92 root 1.1
93     Registers a C callback the be invoked whenever the async interrupt is
94     signalled.
95    
96     The C callback must have the following prototype:
97    
98 root 1.2 void c_func (pTHX_ void *c_arg, int value);
99 root 1.1
100 root 1.2 Both C<$c_func> and C<$c_arg> must be specified as integers/IVs, and
101     C<$value> is the C<value> passed to some earlier call to either C<$signal>
102     or the C<signal_func> function.
103 root 1.1
104     Note that, because the callback can be invoked at almost any time, you
105     have to be careful at saving and restoring global variables that Perl
106 root 1.4 might use (the exception is C<errno>, which is saved and restored by
107 root 1.2 Async::Interrupt). The callback itself runs as part of the perl context,
108     so you can call any perl functions and modify any perl data structures (in
109 root 1.4 which case the requirements set out for C<cb> apply as well).
110 root 1.1
111 root 1.6 =item signal => $signame_or_value
112    
113     When this parameter is specified, then the Async::Interrupt will hook the
114     given signal, that is, it will effectively call C<< ->signal (0) >> each time
115     the given signal is caught by the process.
116    
117     Only one async can hook a given signal, and the signal will be restored to
118     defaults when the Async::Interrupt object gets destroyed.
119    
120 root 1.2 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
121 root 1.1
122 root 1.2 Specifies two file descriptors (or file handles) that should be signalled
123 root 1.1 whenever the async interrupt is signalled. This means a single octet will
124     be written to it, and before the callback is being invoked, it will be
125     read again. Due to races, it is unlikely but possible that multiple octets
126 root 1.2 are written. It is required that the file handles are both in nonblocking
127     mode.
128 root 1.1
129 root 1.6 You can get a portable pipe and set non-blocking mode portably by using
130     e.g. L<AnyEvent::Util> from the L<AnyEvent> distribution.
131    
132     It is also possible to pass in a linux eventfd as both read and write
133     handle (which is faster than a pipe).
134 root 1.1
135 root 1.2 The object will keep a reference to the file handles.
136 root 1.1
137     This can be used to ensure that async notifications will interrupt event
138     frameworks as well.
139    
140     =back
141    
142     =cut
143    
144     sub new {
145     my ($class, %arg) = @_;
146    
147 root 1.6 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class
148 root 1.1 }
149    
150 root 1.2 =item ($signal_func, $signal_arg) = $async->signal_func
151 root 1.1
152     Returns the address of a function to call asynchronously. The function has
153     the following prototype and needs to be passed the specified C<$c_arg>,
154     which is a C<void *> cast to C<IV>:
155    
156     void (*signal_func) (void *signal_arg, int value)
157    
158     An example call would look like:
159    
160     signal_func (signal_arg, 0);
161    
162 root 1.2 The function is safe to call from within signal and thread contexts, at
163 root 1.1 any time. The specified C<value> is passed to both C and Perl callback.
164    
165 root 1.2 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
166     portable).
167    
168 root 1.1 If the function is called while the Async::Interrupt object is already
169     signaled but before the callbacks are being executed, then the stored
170 root 1.2 C<value> is either the old or the new one. Due to the asynchronous
171     nature of the code, the C<value> can even be passed to two consecutive
172     invocations of the callback.
173 root 1.1
174     =item $async->signal ($value=0)
175    
176     This signals the given async object from Perl code. Semi-obviously, this
177     will instantly trigger the callback invocation.
178    
179 root 1.2 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
180     portable).
181    
182     =item $async->block
183    
184 root 1.3 =item $async->unblock
185    
186     Sometimes you need a "critical section" of code that will not be
187     interrupted by an Async::Interrupt. This can be implemented by calling C<<
188     $async->block >> before the critical section, and C<< $async->unblock >>
189     afterwards.
190    
191 root 1.4 Note that there must be exactly one call of C<unblock> for every previous
192 root 1.3 call to C<block> (i.e. calls can nest).
193    
194 root 1.4 Since ensuring this in the presence of exceptions and threads is
195 root 1.3 usually more difficult than you imagine, I recommend using C<<
196     $async->scoped_block >> instead.
197 root 1.2
198 root 1.3 =item $async->scope_block
199    
200     This call C<< $async->block >> and installs a handler that is called when
201     the current scope is exited (via an exception, by canceling the Coro
202     thread, by calling last/goto etc.).
203    
204     This is the recommended (and fastest) way to implement critical sections.
205 root 1.2
206 root 1.6 =item $async->pipe_enable
207    
208     =item $async->pipe_disable
209    
210     Enable/disable signalling the pipe when the interrupt occurs (default is
211     enabled). Writing to a pipe is relatively expensive, so it can be disabled
212     when you know you are not waiting for it (for example, with L<EV> you
213     could disable the pipe in a check watcher, and enable it in a prepare
214     watcher).
215    
216     Note that when C<fd_disable> is in effect, no attempt to read from the
217     pipe will be done.
218    
219 root 1.1 =cut
220    
221     1;
222    
223     =back
224    
225 root 1.2 =head1 EXAMPLE
226    
227 root 1.4 There really should be a complete C/XS example. Bug me about it.
228 root 1.2
229     =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
230    
231 root 1.4 This module works by "hijacking" SIGKILL, which is guaranteed to be always
232 root 1.2 available in perl, but also cannot be caught, so is always available.
233    
234     Basically, this module fakes the receive of a SIGKILL signal and
235     then catches it. This makes normal signal handling slower (probably
236     unmeasurably), but has the advantage of not requiring a special runops nor
237     slowing down normal perl execution a bit.
238    
239     It assumes that C<sig_atomic_t> and C<int> are both exception-safe to
240     modify (C<sig_atomic_> is used by this module, and perl itself uses
241 root 1.4 C<int>, so we can assume that this is quite portable, at least w.r.t.
242 root 1.2 signals).
243    
244 root 1.1 =head1 AUTHOR
245    
246     Marc Lehmann <schmorp@schmorp.de>
247     http://home.schmorp.de/
248    
249     =cut
250