ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Async-Interrupt/Interrupt.pm
(Generate patch)

Comparing Async-Interrupt/Interrupt.pm (file contents):
Revision 1.8 by root, Sun Jul 12 01:44:01 2009 UTC vs.
Revision 1.14 by root, Fri Jul 17 01:53:41 2009 UTC

94 94
95=cut 95=cut
96 96
97package Async::Interrupt; 97package Async::Interrupt;
98 98
99no warnings; 99use common::sense;
100 100
101BEGIN { 101BEGIN {
102 # the next line forces initialisation of internal
103 # signal handling # variables
104 $SIG{KILL} = sub { };
105
102 $VERSION = '0.04'; 106 our $VERSION = '0.5';
103 107
104 require XSLoader; 108 require XSLoader;
105 XSLoader::load Async::Interrupt::, $VERSION; 109 XSLoader::load ("Async::Interrupt", $VERSION);
106} 110}
107 111
108our $DIED = sub { warn "$@" }; 112our $DIED = sub { warn "$@" };
109 113
110=item $async = new Async::Interrupt key => value... 114=item $async = new Async::Interrupt key => value...
153might use (the exception is C<errno>, which is saved and restored by 157might use (the exception is C<errno>, which is saved and restored by
154Async::Interrupt). The callback itself runs as part of the perl context, 158Async::Interrupt). The callback itself runs as part of the perl context,
155so you can call any perl functions and modify any perl data structures (in 159so you can call any perl functions and modify any perl data structures (in
156which case the requirements set out for C<cb> apply as well). 160which case the requirements set out for C<cb> apply as well).
157 161
162=item var => $scalar_ref
163
164When specified, then the given argument must be a reference to a
165scalar. The scalar will be set to C<0> intiially. Signalling the interrupt
166object will set it to the passed value, handling the interrupt will reset
167it to C<0> again.
168
169Note that the only thing you are legally allowed to do is to is to check
170the variable in a boolean or integer context (e.g. comparing it with a
171string, or printing it, will I<destroy> it and might cause your program to
172crash or worse).
173
158=item signal => $signame_or_value 174=item signal => $signame_or_value
159 175
160When this parameter is specified, then the Async::Interrupt will hook the 176When this parameter is specified, then the Async::Interrupt will hook the
161given signal, that is, it will effectively call C<< ->signal (0) >> each time 177given signal, that is, it will effectively call C<< ->signal (0) >> each time
162the given signal is caught by the process. 178the given signal is caught by the process.
171be written to it, and before the callback is being invoked, it will be 187be written to it, and before the callback is being invoked, it will be
172read again. Due to races, it is unlikely but possible that multiple octets 188read again. Due to races, it is unlikely but possible that multiple octets
173are written. It is required that the file handles are both in nonblocking 189are written. It is required that the file handles are both in nonblocking
174mode. 190mode.
175 191
176You can get a portable pipe and set non-blocking mode portably by using
177e.g. L<AnyEvent::Util> from the L<AnyEvent> distribution.
178
179It is also possible to pass in a linux eventfd as both read and write
180handle (which is faster than a pipe).
181
182The object will keep a reference to the file handles. 192The object will keep a reference to the file handles.
183 193
184This can be used to ensure that async notifications will interrupt event 194This can be used to ensure that async notifications will interrupt event
185frameworks as well. 195frameworks as well.
186 196
197Note that C<Async::Interrupt> will create a suitable signal fd
198automatically when your program requests one, so you don't have to specify
199this agrument when all you want is an extra file descriptor to watch.
200
187=back 201=back
188 202
189=cut 203=cut
190 204
191sub new { 205sub new {
192 my ($class, %arg) = @_; 206 my ($class, %arg) = @_;
193 207
194 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class 208 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}, $arg{var}), $class
195} 209}
196 210
197=item ($signal_func, $signal_arg) = $async->signal_func 211=item ($signal_func, $signal_arg) = $async->signal_func
198 212
199Returns the address of a function to call asynchronously. The function has 213Returns the address of a function to call asynchronously. The function has
207 signal_func (signal_arg, 0); 221 signal_func (signal_arg, 0);
208 222
209The function is safe to call from within signal and thread contexts, at 223The function is safe to call from within signal and thread contexts, at
210any time. The specified C<value> is passed to both C and Perl callback. 224any time. The specified C<value> is passed to both C and Perl callback.
211 225
212C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is 226C<$value> must be in the valid range for a C<sig_atomic_t>, except C<0>
213portable). 227(1..127 is portable).
214 228
215If the function is called while the Async::Interrupt object is already 229If the function is called while the Async::Interrupt object is already
216signaled but before the callbacks are being executed, then the stored 230signaled but before the callbacks are being executed, then the stored
217C<value> is either the old or the new one. Due to the asynchronous 231C<value> is either the old or the new one. Due to the asynchronous
218nature of the code, the C<value> can even be passed to two consecutive 232nature of the code, the C<value> can even be passed to two consecutive
219invocations of the callback. 233invocations of the callback.
220 234
235=item $address = $async->c_var
236
237Returns the address (cast to IV) of an C<IV> variable. The variable is set
238to C<0> initially and gets set to the passed value whenever the object
239gets signalled, and reset to C<0> once the interrupt has been handled.
240
241Note that it is often beneficial to just call C<PERL_ASYNC_CHECK ()> to
242handle any interrupts.
243
244Example: call some XS function to store the address, then show C code
245waiting for it.
246
247 my_xs_func $async->c_var;
248
249 static IV *valuep;
250
251 void
252 my_xs_func (void *addr)
253 CODE:
254 valuep = (IV *)addr;
255
256 // code in a loop, waiting
257 while (!*valuep)
258 ; // do soemthing
259
221=item $async->signal ($value=0) 260=item $async->signal ($value=1)
222 261
223This signals the given async object from Perl code. Semi-obviously, this 262This signals the given async object from Perl code. Semi-obviously, this
224will instantly trigger the callback invocation. 263will instantly trigger the callback invocation.
225 264
226C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is 265C<$value> must be in the valid range for a C<sig_atomic_t>, except C<0>
227portable). 266(1..127 is portable).
228 267
229=item $async->block 268=item $async->block
230 269
231=item $async->unblock 270=item $async->unblock
232 271
258enabled). Writing to a pipe is relatively expensive, so it can be disabled 297enabled). Writing to a pipe is relatively expensive, so it can be disabled
259when you know you are not waiting for it (for example, with L<EV> you 298when you know you are not waiting for it (for example, with L<EV> you
260could disable the pipe in a check watcher, and enable it in a prepare 299could disable the pipe in a check watcher, and enable it in a prepare
261watcher). 300watcher).
262 301
263Note that when C<fd_disable> is in effect, no attempt to read from the 302Note that currently, while C<pipe_disable> is in effect, no attempt to
264pipe will be done. 303read from the pipe will be done when handling events. This might change as
304soon as I realize why this is a mistake.
305
306=item $fileno = $async->pipe_fileno
307
308Returns the reading side of the signalling pipe. If no signalling pipe is
309currently attached to the object, it will dynamically create one.
310
311Note that the only valid oepration on this file descriptor is to wait
312until it is readable. The fd might belong currently to a pipe, a tcp
313socket, or an eventfd, depending on the platform, and is guaranteed to be
314C<select>able.
315
316=item $async->post_fork
317
318The object will not normally be usable after a fork (as the pipe fd is
319shared between processes). Calling this method after a fork in the child
320ensures that the object will work as expected again. It only needs to be
321called when the async object is used in the child.
322
323This only works when the pipe was created by Async::Interrupt.
324
325Async::Interrupt ensures that the reading file descriptor does not change
326it's value.
265 327
266=cut 328=cut
267 329
2681; 3301;
269 331
283then intercepts the interpreter handling it. This makes normal signal 345then intercepts the interpreter handling it. This makes normal signal
284handling slower (probably unmeasurably, though), but has the advantage 346handling slower (probably unmeasurably, though), but has the advantage
285of not requiring a special runops function, nor slowing down normal perl 347of not requiring a special runops function, nor slowing down normal perl
286execution a bit. 348execution a bit.
287 349
288It assumes that C<sig_atomic_t> and C<int> are both async-safe to modify 350It assumes that C<sig_atomic_t>, C<int> and C<IV> are all async-safe to
289(C<sig_atomic_> is used by this module, and perl itself uses C<int>, so we 351modify.
290can assume that this is quite portable, at least w.r.t. signals).
291 352
292=head1 AUTHOR 353=head1 AUTHOR
293 354
294 Marc Lehmann <schmorp@schmorp.de> 355 Marc Lehmann <schmorp@schmorp.de>
295 http://home.schmorp.de/ 356 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines