… | |
… | |
7 | use Async::Interrupt; |
7 | use Async::Interrupt; |
8 | |
8 | |
9 | =head1 DESCRIPTION |
9 | =head1 DESCRIPTION |
10 | |
10 | |
11 | This module implements a single feature only of interest to advanced perl |
11 | This module implements a single feature only of interest to advanced perl |
12 | modules, namely asynchronous interruptions (think "unix signals", which |
12 | modules, namely asynchronous interruptions (think "UNIX signals", which |
13 | are very similar). |
13 | are very similar). |
14 | |
14 | |
15 | Sometimes, modules wish to run code asynchronously (in another thread), |
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 |
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 |
17 | to write some data to a pipe and use an event handling toolkit to watch |
… | |
… | |
37 | function also takes an integer argument in the range SIG_ATOMIC_MIN to |
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). |
38 | SIG_ATOMIC_MAX (guaranteed to allow at least 0..127). |
39 | |
39 | |
40 | Since this kind of interruption is fast, but can only interrupt a |
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 |
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 |
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. |
43 | |
45 | |
44 | =over 4 |
46 | =over 4 |
45 | |
47 | |
46 | =cut |
48 | =cut |
47 | |
49 | |
48 | package Async::Interrupt; |
50 | package Async::Interrupt; |
49 | |
51 | |
50 | no warnings; |
52 | no warnings; |
51 | |
53 | |
52 | BEGIN { |
54 | BEGIN { |
53 | $VERSION = '0.02'; |
55 | $VERSION = '0.04'; |
54 | |
56 | |
55 | require XSLoader; |
57 | require XSLoader; |
56 | XSLoader::load Async::Interrupt::, $VERSION; |
58 | XSLoader::load Async::Interrupt::, $VERSION; |
57 | } |
59 | } |
58 | |
60 | |
… | |
… | |
99 | C<$value> is the C<value> passed to some earlier call to either C<$signal> |
101 | C<$value> is the C<value> passed to some earlier call to either C<$signal> |
100 | or the C<signal_func> function. |
102 | or the C<signal_func> function. |
101 | |
103 | |
102 | Note that, because the callback can be invoked at almost any time, you |
104 | Note that, because the callback can be invoked at almost any time, you |
103 | have to be careful at saving and restoring global variables that Perl |
105 | have to be careful at saving and restoring global variables that Perl |
104 | might use (the excetpion is C<errno>, which is aved and restored by |
106 | might use (the exception is C<errno>, which is saved and restored by |
105 | Async::Interrupt). The callback itself runs as part of the perl context, |
107 | Async::Interrupt). The callback itself runs as part of the perl context, |
106 | so you can call any perl functions and modify any perl data structures (in |
108 | so you can call any perl functions and modify any perl data structures (in |
107 | which case the requireemnts set out for C<cb> apply as well). |
109 | which case the requirements set out for C<cb> apply as well). |
|
|
110 | |
|
|
111 | =item signal => $signame_or_value |
|
|
112 | |
|
|
113 | When this parameter is specified, then the Async::Interrupt will hook the |
|
|
114 | given signal, that is, it will effectively call C<< ->signal (0) >> each time |
|
|
115 | the given signal is caught by the process. |
|
|
116 | |
|
|
117 | Only one async can hook a given signal, and the signal will be restored to |
|
|
118 | defaults when the Async::Interrupt object gets destroyed. |
108 | |
119 | |
109 | =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] |
120 | =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] |
110 | |
121 | |
111 | Specifies two file descriptors (or file handles) that should be signalled |
122 | Specifies two file descriptors (or file handles) that should be signalled |
112 | whenever the async interrupt is signalled. This means a single octet will |
123 | whenever the async interrupt is signalled. This means a single octet will |
113 | be written to it, and before the callback is being invoked, it will be |
124 | be written to it, and before the callback is being invoked, it will be |
114 | read again. Due to races, it is unlikely but possible that multiple octets |
125 | read again. Due to races, it is unlikely but possible that multiple octets |
115 | are written. It is required that the file handles are both in nonblocking |
126 | are written. It is required that the file handles are both in nonblocking |
116 | mode. |
127 | mode. |
117 | |
128 | |
118 | (You can get a portable pipe and set non-blocking mode portably by using |
129 | You can get a portable pipe and set non-blocking mode portably by using |
119 | e.g. L<AnyEvent::Util> from the L<AnyEvent> distro). |
130 | e.g. L<AnyEvent::Util> from the L<AnyEvent> distribution. |
|
|
131 | |
|
|
132 | It is also possible to pass in a linux eventfd as both read and write |
|
|
133 | handle (which is faster than a pipe). |
120 | |
134 | |
121 | The object will keep a reference to the file handles. |
135 | The object will keep a reference to the file handles. |
122 | |
136 | |
123 | This can be used to ensure that async notifications will interrupt event |
137 | This can be used to ensure that async notifications will interrupt event |
124 | frameworks as well. |
138 | frameworks as well. |
… | |
… | |
128 | =cut |
142 | =cut |
129 | |
143 | |
130 | sub new { |
144 | sub new { |
131 | my ($class, %arg) = @_; |
145 | my ($class, %arg) = @_; |
132 | |
146 | |
133 | bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class |
147 | bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}), $class |
134 | } |
148 | } |
135 | |
149 | |
136 | =item ($signal_func, $signal_arg) = $async->signal_func |
150 | =item ($signal_func, $signal_arg) = $async->signal_func |
137 | |
151 | |
138 | Returns the address of a function to call asynchronously. The function has |
152 | Returns the address of a function to call asynchronously. The function has |
… | |
… | |
165 | C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is |
179 | C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is |
166 | portable). |
180 | portable). |
167 | |
181 | |
168 | =item $async->block |
182 | =item $async->block |
169 | |
183 | |
170 | Sometimes you need a "critical section" of code where |
|
|
171 | |
|
|
172 | =item $async->unblock |
184 | =item $async->unblock |
173 | |
185 | |
|
|
186 | Sometimes you need a "critical section" of code that will not be |
|
|
187 | interrupted by an Async::Interrupt. This can be implemented by calling C<< |
|
|
188 | $async->block >> before the critical section, and C<< $async->unblock >> |
|
|
189 | afterwards. |
|
|
190 | |
|
|
191 | Note that there must be exactly one call of C<unblock> for every previous |
|
|
192 | call to C<block> (i.e. calls can nest). |
|
|
193 | |
|
|
194 | Since ensuring this in the presence of exceptions and threads is |
|
|
195 | usually more difficult than you imagine, I recommend using C<< |
|
|
196 | $async->scoped_block >> instead. |
|
|
197 | |
|
|
198 | =item $async->scope_block |
|
|
199 | |
|
|
200 | This call C<< $async->block >> and installs a handler that is called when |
|
|
201 | the current scope is exited (via an exception, by canceling the Coro |
|
|
202 | thread, by calling last/goto etc.). |
|
|
203 | |
|
|
204 | This is the recommended (and fastest) way to implement critical sections. |
|
|
205 | |
|
|
206 | =item $async->pipe_enable |
|
|
207 | |
|
|
208 | =item $async->pipe_disable |
|
|
209 | |
|
|
210 | Enable/disable signalling the pipe when the interrupt occurs (default is |
|
|
211 | enabled). Writing to a pipe is relatively expensive, so it can be disabled |
|
|
212 | when you know you are not waiting for it (for example, with L<EV> you |
|
|
213 | could disable the pipe in a check watcher, and enable it in a prepare |
|
|
214 | watcher). |
|
|
215 | |
|
|
216 | Note that when C<fd_disable> is in effect, no attempt to read from the |
|
|
217 | pipe will be done. |
|
|
218 | |
174 | =cut |
219 | =cut |
175 | |
220 | |
176 | 1; |
221 | 1; |
177 | |
222 | |
178 | =back |
223 | =back |
179 | |
224 | |
180 | =head1 EXAMPLE |
225 | =head1 EXAMPLE |
181 | |
226 | |
182 | #TODO |
227 | There really should be a complete C/XS example. Bug me about it. |
183 | |
228 | |
184 | =head1 IMPLEMENTATION DETAILS AND LIMITATIONS |
229 | =head1 IMPLEMENTATION DETAILS AND LIMITATIONS |
185 | |
230 | |
186 | This module works by "hijacking" SIGKILL, which is guarenteed to be always |
231 | This module works by "hijacking" SIGKILL, which is guaranteed to be always |
187 | available in perl, but also cannot be caught, so is always available. |
232 | available in perl, but also cannot be caught, so is always available. |
188 | |
233 | |
189 | Basically, this module fakes the receive of a SIGKILL signal and |
234 | Basically, this module fakes the receive of a SIGKILL signal and |
190 | then catches it. This makes normal signal handling slower (probably |
235 | then catches it. This makes normal signal handling slower (probably |
191 | unmeasurably), but has the advantage of not requiring a special runops nor |
236 | unmeasurably), but has the advantage of not requiring a special runops nor |
192 | slowing down normal perl execution a bit. |
237 | slowing down normal perl execution a bit. |
193 | |
238 | |
194 | It assumes that C<sig_atomic_t> and C<int> are both exception-safe to |
239 | It assumes that C<sig_atomic_t> and C<int> are both exception-safe to |
195 | modify (C<sig_atomic_> is used by this module, and perl itself uses |
240 | modify (C<sig_atomic_> is used by this module, and perl itself uses |
196 | C<int>, so we can assume that this is quite portbale, at least w.r.t. |
241 | C<int>, so we can assume that this is quite portable, at least w.r.t. |
197 | signals). |
242 | signals). |
198 | |
243 | |
199 | =head1 AUTHOR |
244 | =head1 AUTHOR |
200 | |
245 | |
201 | Marc Lehmann <schmorp@schmorp.de> |
246 | Marc Lehmann <schmorp@schmorp.de> |