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

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 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 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 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
46 =over 4
47
48 =cut
49
50 package Async::Interrupt;
51
52 no warnings;
53
54 BEGIN {
55 $VERSION = '0.03';
56
57 require XSLoader;
58 XSLoader::load Async::Interrupt::, $VERSION;
59 }
60
61 our $DIED = sub { warn "$@" };
62
63 =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 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
86 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
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 void c_func (pTHX_ void *c_arg, int value);
99
100 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
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 might use (the exception is C<errno>, which is saved and restored by
107 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 which case the requirements set out for C<cb> apply as well).
110
111 =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 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
121
122 Specifies two file descriptors (or file handles) that should be signalled
123 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 are written. It is required that the file handles are both in nonblocking
127 mode.
128
129 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
135 The object will keep a reference to the file handles.
136
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 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class
148 }
149
150 =item ($signal_func, $signal_arg) = $async->signal_func
151
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 The function is safe to call from within signal and thread contexts, at
163 any time. The specified C<value> is passed to both C and Perl callback.
164
165 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
166 portable).
167
168 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 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
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 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 =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 Note that there must be exactly one call of C<unblock> for every previous
192 call to C<block> (i.e. calls can nest).
193
194 Since ensuring this in the presence of exceptions and threads is
195 usually more difficult than you imagine, I recommend using C<<
196 $async->scoped_block >> instead.
197
198 =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
206 =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 =cut
220
221 1;
222
223 =back
224
225 =head1 EXAMPLE
226
227 There really should be a complete C/XS example. Bug me about it.
228
229 =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
230
231 This module works by "hijacking" SIGKILL, which is guaranteed to be always
232 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 C<int>, so we can assume that this is quite portable, at least w.r.t.
242 signals).
243
244 =head1 AUTHOR
245
246 Marc Lehmann <schmorp@schmorp.de>
247 http://home.schmorp.de/
248
249 =cut
250