ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
Revision: 1.3
Committed: Thu Jul 2 16:12:40 2009 UTC (14 years, 11 months ago) by root
Branch: MAIN
Changes since 1.2: +21 -2 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 while
43 #TODO#
44
45 =over 4
46
47 =cut
48
49 package Async::Interrupt;
50
51 no warnings;
52
53 BEGIN {
54 $VERSION = '0.02';
55
56 require XSLoader;
57 XSLoader::load Async::Interrupt::, $VERSION;
58 }
59
60 our $DIED = sub { warn "$@" };
61
62 =item $async = new Async::Interrupt key => value...
63
64 Creates a new Async::Interrupt object. You may only use async
65 notifications on this object while it exists, so you need to keep a
66 reference to it at all times while it is used.
67
68 Optional constructor arguments include (normally you would specify at
69 least one of C<cb> or C<c_cb>).
70
71 =over 4
72
73 =item cb => $coderef->($value)
74
75 Registers a perl callback to be invoked whenever the async interrupt is
76 signalled.
77
78 Note that, since this callback can be invoked at basically any time, it
79 must not modify any well-known global variables such as C<$/> without
80 restoring them again before returning.
81
82 The exceptions are C<$!> and C<$@>, which are saved and restored by
83 Async::Interrupt.
84
85 If the callback should throw an exception, then it will be caught,
86 and C<$Async::Interrupt::DIED> will be called with C<$@> containing
87 the exception. The default will simply C<warn> about the message and
88 continue.
89
90 =item c_cb => [$c_func, $c_arg]
91
92 Registers a C callback the be invoked whenever the async interrupt is
93 signalled.
94
95 The C callback must have the following prototype:
96
97 void c_func (pTHX_ void *c_arg, int value);
98
99 Both C<$c_func> and C<$c_arg> must be specified as integers/IVs, and
100 C<$value> is the C<value> passed to some earlier call to either C<$signal>
101 or the C<signal_func> function.
102
103 Note that, because the callback can be invoked at almost any time, you
104 have to be careful at saving and restoring global variables that Perl
105 might use (the excetpion is C<errno>, which is aved and restored by
106 Async::Interrupt). The callback itself runs as part of the perl context,
107 so you can call any perl functions and modify any perl data structures (in
108 which case the requireemnts set out for C<cb> apply as well).
109
110 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
111
112 Specifies two file descriptors (or file handles) that should be signalled
113 whenever the async interrupt is signalled. This means a single octet will
114 be written to it, and before the callback is being invoked, it will be
115 read again. Due to races, it is unlikely but possible that multiple octets
116 are written. It is required that the file handles are both in nonblocking
117 mode.
118
119 (You can get a portable pipe and set non-blocking mode portably by using
120 e.g. L<AnyEvent::Util> from the L<AnyEvent> distro).
121
122 The object will keep a reference to the file handles.
123
124 This can be used to ensure that async notifications will interrupt event
125 frameworks as well.
126
127 =back
128
129 =cut
130
131 sub new {
132 my ($class, %arg) = @_;
133
134 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class
135 }
136
137 =item ($signal_func, $signal_arg) = $async->signal_func
138
139 Returns the address of a function to call asynchronously. The function has
140 the following prototype and needs to be passed the specified C<$c_arg>,
141 which is a C<void *> cast to C<IV>:
142
143 void (*signal_func) (void *signal_arg, int value)
144
145 An example call would look like:
146
147 signal_func (signal_arg, 0);
148
149 The function is safe to call from within signal and thread contexts, at
150 any time. The specified C<value> is passed to both C and Perl callback.
151
152 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
153 portable).
154
155 If the function is called while the Async::Interrupt object is already
156 signaled but before the callbacks are being executed, then the stored
157 C<value> is either the old or the new one. Due to the asynchronous
158 nature of the code, the C<value> can even be passed to two consecutive
159 invocations of the callback.
160
161 =item $async->signal ($value=0)
162
163 This signals the given async object from Perl code. Semi-obviously, this
164 will instantly trigger the callback invocation.
165
166 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
167 portable).
168
169 =item $async->block
170
171 =item $async->unblock
172
173 Sometimes you need a "critical section" of code that will not be
174 interrupted by an Async::Interrupt. This can be implemented by calling C<<
175 $async->block >> before the critical section, and C<< $async->unblock >>
176 afterwards.
177
178 Note that there must be exactly one call of C<unblock> for ever<y previous
179 call to C<block> (i.e. calls can nest).
180
181 Since ensuring this in the presense of exceptions and threads is
182 usually more difficult than you imagine, I recommend using C<<
183 $async->scoped_block >> instead.
184
185 =item $async->scope_block
186
187 This call C<< $async->block >> and installs a handler that is called when
188 the current scope is exited (via an exception, by canceling the Coro
189 thread, by calling last/goto etc.).
190
191 This is the recommended (and fastest) way to implement critical sections.
192
193 =cut
194
195 1;
196
197 =back
198
199 =head1 EXAMPLE
200
201 #TODO
202
203 =head1 IMPLEMENTATION DETAILS AND LIMITATIONS
204
205 This module works by "hijacking" SIGKILL, which is guarenteed to be always
206 available in perl, but also cannot be caught, so is always available.
207
208 Basically, this module fakes the receive of a SIGKILL signal and
209 then catches it. This makes normal signal handling slower (probably
210 unmeasurably), but has the advantage of not requiring a special runops nor
211 slowing down normal perl execution a bit.
212
213 It assumes that C<sig_atomic_t> and C<int> are both exception-safe to
214 modify (C<sig_atomic_> is used by this module, and perl itself uses
215 C<int>, so we can assume that this is quite portbale, at least w.r.t.
216 signals).
217
218 =head1 AUTHOR
219
220 Marc Lehmann <schmorp@schmorp.de>
221 http://home.schmorp.de/
222
223 =cut
224