… | |
… | |
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 | or from a signal handler), and then signal the perl interpreter on |
17 | to write some data to a pipe and use an event handling toolkit to watch |
17 | certain events. One common way is to write some data to a pipe and use an |
18 | for I/O events. Another way is to send a signal. Those methods are slow, |
18 | event handling toolkit to watch for I/O events. Another way is to send |
19 | and in the case of a pipe, also not asynchronous - it won't interrupt a |
19 | a signal. Those methods are slow, and in the case of a pipe, also not |
20 | running perl interpreter. |
20 | asynchronous - it won't interrupt a running perl interpreter. |
21 | |
21 | |
22 | This module implements asynchronous notifications that enable you to |
22 | This module implements asynchronous notifications that enable you to |
23 | signal running perl code form another thread, asynchronously, without |
23 | signal running perl code from another thread, asynchronously, and |
24 | issuing syscalls. |
24 | sometimes even without using a single syscall. |
25 | |
25 | |
26 | It works by creating an C<Async::Interrupt> object for each such use. This |
26 | =head2 USAGE SCENARIOS |
27 | object stores a perl and/or a C-level callback that is invoked when the |
27 | |
28 | C<Async::Interrupt> object gets signalled. It is executed at the next time |
28 | =over 4 |
29 | the perl interpreter is running (i.e. it will interrupt a computation, but |
29 | |
30 | not an XS function or a syscall). |
30 | =item Race-free signal handling |
|
|
31 | |
|
|
32 | There seems to be no way to do race-free signal handling in perl: to |
|
|
33 | catch a signal, you have to execute Perl code, and between entering the |
|
|
34 | interpreter C<select> function (or other blocking functions) and executing |
|
|
35 | the select syscall is a small but relevant timespan during which signals |
|
|
36 | will be queued, but perl signal handlers will not be executed and the |
|
|
37 | blocking syscall will not be interrupted. |
|
|
38 | |
|
|
39 | You can use this module to bind a signal to a callback while at the same |
|
|
40 | time activating an event pipe that you can C<select> on, fixing the race |
|
|
41 | completely. |
|
|
42 | |
|
|
43 | This can be used to implement the signal hadling in event loops, |
|
|
44 | e.g. L<AnyEvent>, L<POE>, L<IO::Async::Loop> and so on. |
|
|
45 | |
|
|
46 | =item Background threads want speedy reporting |
|
|
47 | |
|
|
48 | Assume you want very exact timing, and you can spare an extra cpu core |
|
|
49 | for that. Then you can run an extra thread that signals your perl |
|
|
50 | interpreter. This means you can get a very exact timing source while your |
|
|
51 | perl code is number crunching, without even using a syscall to communicate |
|
|
52 | between your threads. |
|
|
53 | |
|
|
54 | For example the deliantra game server uses a variant of this technique |
|
|
55 | to interrupt background processes regularly to send map updates to game |
|
|
56 | clients. |
|
|
57 | |
|
|
58 | L<IO::AIO> and L<BDB> could also use this to speed up result reporting. |
|
|
59 | |
|
|
60 | =item Speedy event loop invocation |
|
|
61 | |
|
|
62 | One could use this module e.g. in L<Coro> to interrupt a running coro-thread |
|
|
63 | and cause it to enter the event loop. |
|
|
64 | |
|
|
65 | Or one could bind to C<SIGIO> and tell some important sockets to send this |
|
|
66 | signal, causing the event loop to be entered to reduce network latency. |
|
|
67 | |
|
|
68 | =back |
|
|
69 | |
|
|
70 | =head2 HOW TO USE |
|
|
71 | |
|
|
72 | You can use this module by creating an C<Async::Interrupt> object for each |
|
|
73 | such event source. This object stores a perl and/or a C-level callback |
|
|
74 | that is invoked when the C<Async::Interrupt> object gets signalled. It is |
|
|
75 | executed at the next time the perl interpreter is running (i.e. it will |
|
|
76 | interrupt a computation, but not an XS function or a syscall). |
31 | |
77 | |
32 | You can signal the C<Async::Interrupt> object either by calling it's C<< |
78 | 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. |
79 | ->signal >> method, or, more commonly, by calling a C function. There is |
|
|
80 | also the built-in (POSIX) signal source. |
34 | |
81 | |
35 | The C<< ->signal_func >> returns the address of the C function that is to |
82 | 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 |
83 | 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 |
84 | function also takes an integer argument in the range SIG_ATOMIC_MIN to |
38 | SIG_ATOMIC_MAX (guaranteed to allow at least 0..127). |
85 | SIG_ATOMIC_MAX (guaranteed to allow at least 0..127). |
39 | |
86 | |
40 | Since this kind of interruption is fast, but can only interrupt a |
87 | Since this kind of interruption is fast, but can only interrupt a |
41 | I<running> interpreter, there is optional support for also signalling a |
88 | I<running> interpreter, there is optional support for signalling a pipe |
42 | pipe - that means you can also wait for the pipe to become readable (e.g. |
89 | - that means you can also wait for the pipe to become readable (e.g. via |
43 | via L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a |
90 | L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a C<read> |
44 | C<read> and C<write> syscall. |
91 | and C<write> syscall. |
45 | |
92 | |
46 | =over 4 |
93 | =over 4 |
47 | |
94 | |
48 | =cut |
95 | =cut |
49 | |
96 | |
50 | package Async::Interrupt; |
97 | package Async::Interrupt; |
51 | |
98 | |
52 | no warnings; |
99 | no warnings; |
53 | |
100 | |
54 | BEGIN { |
101 | BEGIN { |
55 | $VERSION = '0.04'; |
102 | $VERSION = '0.041'; |
56 | |
103 | |
57 | require XSLoader; |
104 | require XSLoader; |
58 | XSLoader::load Async::Interrupt::, $VERSION; |
105 | XSLoader::load Async::Interrupt::, $VERSION; |
59 | } |
106 | } |
60 | |
107 | |
… | |
… | |
222 | |
269 | |
223 | =back |
270 | =back |
224 | |
271 | |
225 | =head1 EXAMPLE |
272 | =head1 EXAMPLE |
226 | |
273 | |
227 | There really should be a complete C/XS example. Bug me about it. |
274 | There really should be a complete C/XS example. Bug me about it. Better |
|
|
275 | yet, create one. |
228 | |
276 | |
229 | =head1 IMPLEMENTATION DETAILS AND LIMITATIONS |
277 | =head1 IMPLEMENTATION DETAILS AND LIMITATIONS |
230 | |
278 | |
231 | This module works by "hijacking" SIGKILL, which is guaranteed to be always |
279 | This module works by "hijacking" SIGKILL, which is guaranteed to always |
232 | available in perl, but also cannot be caught, so is always available. |
280 | exist, but also cannot be caught, so is always available. |
233 | |
281 | |
234 | Basically, this module fakes the receive of a SIGKILL signal and |
282 | Basically, this module fakes the occurance of a SIGKILL signal and |
235 | then catches it. This makes normal signal handling slower (probably |
283 | then intercepts the interpreter handling it. This makes normal signal |
236 | unmeasurably), but has the advantage of not requiring a special runops nor |
284 | handling slower (probably unmeasurably, though), but has the advantage |
237 | slowing down normal perl execution a bit. |
285 | of not requiring a special runops function, nor slowing down normal perl |
|
|
286 | execution a bit. |
238 | |
287 | |
239 | It assumes that C<sig_atomic_t> and C<int> are both exception-safe to |
288 | It assumes that C<sig_atomic_t> and C<int> are both async-safe to modify |
240 | modify (C<sig_atomic_> is used by this module, and perl itself uses |
289 | (C<sig_atomic_> is used by this module, and perl itself uses C<int>, so we |
241 | C<int>, so we can assume that this is quite portable, at least w.r.t. |
290 | can assume that this is quite portable, at least w.r.t. signals). |
242 | signals). |
|
|
243 | |
291 | |
244 | =head1 AUTHOR |
292 | =head1 AUTHOR |
245 | |
293 | |
246 | Marc Lehmann <schmorp@schmorp.de> |
294 | Marc Lehmann <schmorp@schmorp.de> |
247 | http://home.schmorp.de/ |
295 | http://home.schmorp.de/ |