ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
Revision: 1.4
Committed: Thu Jul 2 16:15:52 2009 UTC (14 years, 11 months ago) by root
Branch: MAIN
CVS Tags: rel-0_02
Changes since 1.3: +12 -11 lines
Log Message:
0.02

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.02';
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 pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
112
113 Specifies two file descriptors (or file handles) that should be signalled
114 whenever the async interrupt is signalled. This means a single octet will
115 be written to it, and before the callback is being invoked, it will be
116 read again. Due to races, it is unlikely but possible that multiple octets
117 are written. It is required that the file handles are both in nonblocking
118 mode.
119
120 (You can get a portable pipe and set non-blocking mode portably by using
121 e.g. L<AnyEvent::Util> from the L<AnyEvent> distribution).
122
123 The object will keep a reference to the file handles.
124
125 This can be used to ensure that async notifications will interrupt event
126 frameworks as well.
127
128 =back
129
130 =cut
131
132 sub new {
133 my ($class, %arg) = @_;
134
135 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class
136 }
137
138 =item ($signal_func, $signal_arg) = $async->signal_func
139
140 Returns the address of a function to call asynchronously. The function has
141 the following prototype and needs to be passed the specified C<$c_arg>,
142 which is a C<void *> cast to C<IV>:
143
144 void (*signal_func) (void *signal_arg, int value)
145
146 An example call would look like:
147
148 signal_func (signal_arg, 0);
149
150 The function is safe to call from within signal and thread contexts, at
151 any time. The specified C<value> is passed to both C and Perl callback.
152
153 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
154 portable).
155
156 If the function is called while the Async::Interrupt object is already
157 signaled but before the callbacks are being executed, then the stored
158 C<value> is either the old or the new one. Due to the asynchronous
159 nature of the code, the C<value> can even be passed to two consecutive
160 invocations of the callback.
161
162 =item $async->signal ($value=0)
163
164 This signals the given async object from Perl code. Semi-obviously, this
165 will instantly trigger the callback invocation.
166
167 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
168 portable).
169
170 =item $async->block
171
172 =item $async->unblock
173
174 Sometimes you need a "critical section" of code that will not be
175 interrupted by an Async::Interrupt. This can be implemented by calling C<<
176 $async->block >> before the critical section, and C<< $async->unblock >>
177 afterwards.
178
179 Note that there must be exactly one call of C<unblock> for every previous
180 call to C<block> (i.e. calls can nest).
181
182 Since ensuring this in the presence of exceptions and threads is
183 usually more difficult than you imagine, I recommend using C<<
184 $async->scoped_block >> instead.
185
186 =item $async->scope_block
187
188 This call C<< $async->block >> and installs a handler that is called when
189 the current scope is exited (via an exception, by canceling the Coro
190 thread, by calling last/goto etc.).
191
192 This is the recommended (and fastest) way to implement critical sections.
193
194 =cut
195
196 1;
197
198 =back
199
200 =head1 EXAMPLE
201
202 There really should be a complete C/XS example. Bug me about it.
203
204 =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
205
206 This module works by "hijacking" SIGKILL, which is guaranteed to be always
207 available in perl, but also cannot be caught, so is always available.
208
209 Basically, this module fakes the receive of a SIGKILL signal and
210 then catches it. This makes normal signal handling slower (probably
211 unmeasurably), but has the advantage of not requiring a special runops nor
212 slowing down normal perl execution a bit.
213
214 It assumes that C<sig_atomic_t> and C<int> are both exception-safe to
215 modify (C<sig_atomic_> is used by this module, and perl itself uses
216 C<int>, so we can assume that this is quite portable, at least w.r.t.
217 signals).
218
219 =head1 AUTHOR
220
221 Marc Lehmann <schmorp@schmorp.de>
222 http://home.schmorp.de/
223
224 =cut
225