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

# User Rev Content
1 root 1.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 root 1.2 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 root 1.3 #TODO#
44 root 1.2
45 root 1.1 =over 4
46    
47     =cut
48    
49     package Async::Interrupt;
50    
51 root 1.2 no warnings;
52    
53 root 1.1 BEGIN {
54     $VERSION = '0.02';
55    
56     require XSLoader;
57     XSLoader::load Async::Interrupt::, $VERSION;
58     }
59    
60 root 1.2 our $DIED = sub { warn "$@" };
61    
62 root 1.1 =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 root 1.2 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 root 1.1
85 root 1.2 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 root 1.1
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 root 1.2 void c_func (pTHX_ void *c_arg, int value);
98 root 1.1
99 root 1.2 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 root 1.1
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 root 1.2 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 root 1.1
110 root 1.2 =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing]
111 root 1.1
112 root 1.2 Specifies two file descriptors (or file handles) that should be signalled
113 root 1.1 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 root 1.2 are written. It is required that the file handles are both in nonblocking
117     mode.
118 root 1.1
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 root 1.2 The object will keep a reference to the file handles.
123 root 1.1
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 root 1.2 bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class
135 root 1.1 }
136    
137 root 1.2 =item ($signal_func, $signal_arg) = $async->signal_func
138 root 1.1
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 root 1.2 The function is safe to call from within signal and thread contexts, at
150 root 1.1 any time. The specified C<value> is passed to both C and Perl callback.
151    
152 root 1.2 C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is
153     portable).
154    
155 root 1.1 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 root 1.2 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 root 1.1
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 root 1.2 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 root 1.3 =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 root 1.2
185 root 1.3 =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 root 1.2
193 root 1.1 =cut
194    
195     1;
196    
197     =back
198    
199 root 1.2 =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 root 1.1 =head1 AUTHOR
219    
220     Marc Lehmann <schmorp@schmorp.de>
221     http://home.schmorp.de/
222    
223     =cut
224