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

Comparing cvsroot/Async-Interrupt/Interrupt.pm (file contents):
Revision 1.1 by root, Thu Jul 2 13:41:44 2009 UTC vs.
Revision 1.6 by root, Sat Jul 11 22:16:50 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines