… | |
… | |
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 form another thread, asynchronously, without |
24 | issuing syscalls. |
24 | issuing syscalls. |
25 | |
25 | |
|
|
26 | 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 | |
26 | =over 4 |
44 | =over 4 |
27 | |
45 | |
28 | =cut |
46 | =cut |
29 | |
47 | |
30 | package Async::Interrupt; |
48 | package Async::Interrupt; |
|
|
49 | |
|
|
50 | no warnings; |
31 | |
51 | |
32 | BEGIN { |
52 | BEGIN { |
33 | $VERSION = '0.02'; |
53 | $VERSION = '0.02'; |
34 | |
54 | |
35 | require XSLoader; |
55 | require XSLoader; |
36 | XSLoader::load Async::Interrupt::, $VERSION; |
56 | XSLoader::load Async::Interrupt::, $VERSION; |
37 | } |
57 | } |
38 | |
58 | |
|
|
59 | our $DIED = sub { warn "$@" }; |
|
|
60 | |
39 | =item $async = new Async::Interrupt key => value... |
61 | =item $async = new Async::Interrupt key => value... |
40 | |
62 | |
41 | Creates a new Async::Interrupt object. You may only use async |
63 | Creates a new Async::Interrupt object. You may only use async |
42 | notifications on this object while it exists, so you need to keep a |
64 | notifications on this object while it exists, so you need to keep a |
43 | reference to it at all times while it is used. |
65 | reference to it at all times while it is used. |
… | |
… | |
51 | |
73 | |
52 | Registers a perl callback to be invoked whenever the async interrupt is |
74 | Registers a perl callback to be invoked whenever the async interrupt is |
53 | signalled. |
75 | signalled. |
54 | |
76 | |
55 | Note that, since this callback can be invoked at basically any time, it |
77 | Note that, since this callback can be invoked at basically any time, it |
56 | must not modify any well-known global variables such as C<$/>, C<$@> or |
78 | must not modify any well-known global variables such as C<$/> without |
57 | C<$!>, without restoring them again before returning. |
79 | restoring them again before returning. |
58 | |
80 | |
|
|
81 | The exceptions are C<$!> and C<$@>, which are saved and restored by |
|
|
82 | Async::Interrupt. |
|
|
83 | |
|
|
84 | If the callback should throw an exception, then it will be caught, |
|
|
85 | and C<$Async::Interrupt::DIED> will be called with C<$@> containing |
|
|
86 | the exception. The default will simply C<warn> about the message and |
|
|
87 | continue. |
|
|
88 | |
59 | =item c_cb => [$c_func, $c_data] |
89 | =item c_cb => [$c_func, $c_arg] |
60 | |
90 | |
61 | Registers a C callback the be invoked whenever the async interrupt is |
91 | Registers a C callback the be invoked whenever the async interrupt is |
62 | signalled. |
92 | signalled. |
63 | |
93 | |
64 | The C callback must have the following prototype: |
94 | The C callback must have the following prototype: |
65 | |
95 | |
66 | void c_func (pTHX_ void *c_data, int value); |
96 | void c_func (pTHX_ void *c_arg, int value); |
67 | |
97 | |
68 | Both C<$c_func> and C<$c_data> must be specified as integers/IVs. |
98 | Both C<$c_func> and C<$c_arg> must be specified as integers/IVs, and |
|
|
99 | C<$value> is the C<value> passed to some earlier call to either C<$signal> |
|
|
100 | or the C<signal_func> function. |
69 | |
101 | |
70 | Note that, because the callback can be invoked at almost any time, you |
102 | Note that, because the callback can be invoked at almost any time, you |
71 | have to be careful at saving and restoring global variables that Perl |
103 | have to be careful at saving and restoring global variables that Perl |
72 | might use, most notably C<errno>. The callback itself runs as part of the |
104 | might use (the excetpion is C<errno>, which is aved and restored by |
73 | perl context, so you can call any perl functions and modify any perl data |
105 | Async::Interrupt). The callback itself runs as part of the perl context, |
74 | structures. |
106 | 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). |
75 | |
108 | |
76 | =item fh => $fileno_or_fh |
109 | =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] |
77 | |
110 | |
78 | Specifies a file descriptor (or file handle) that should be signalled |
111 | Specifies two file descriptors (or file handles) that should be signalled |
79 | whenever the async interrupt is signalled. This means a single octet will |
112 | whenever the async interrupt is signalled. This means a single octet will |
80 | be written to it, and before the callback is being invoked, it will be |
113 | be written to it, and before the callback is being invoked, it will be |
81 | read again. Due to races, it is unlikely but possible that multiple octets |
114 | read again. Due to races, it is unlikely but possible that multiple octets |
82 | are written, therefore, it is recommended that the file handle is in |
115 | are written. It is required that the file handles are both in nonblocking |
83 | nonblocking mode. |
116 | mode. |
84 | |
117 | |
85 | (You can get a portable pipe and set non-blocking mode portably by using |
118 | (You can get a portable pipe and set non-blocking mode portably by using |
86 | e.g. L<AnyEvent::Util> from the L<AnyEvent> distro). |
119 | e.g. L<AnyEvent::Util> from the L<AnyEvent> distro). |
87 | |
120 | |
88 | The object will keep a reference to the file handle. |
121 | The object will keep a reference to the file handles. |
89 | |
122 | |
90 | This can be used to ensure that async notifications will interrupt event |
123 | This can be used to ensure that async notifications will interrupt event |
91 | frameworks as well. |
124 | frameworks as well. |
92 | |
125 | |
93 | =back |
126 | =back |
… | |
… | |
95 | =cut |
128 | =cut |
96 | |
129 | |
97 | sub new { |
130 | sub new { |
98 | my ($class, %arg) = @_; |
131 | my ($class, %arg) = @_; |
99 | |
132 | |
100 | my $self = _alloc $arg{cb}, @{$arg{c_cb}}[0,1], $arg{fh}; |
133 | bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1]), $class |
101 | bless \$self, $class |
|
|
102 | } |
134 | } |
103 | |
135 | |
104 | =item ($signal_func, $signal_arg) = $async->signal_cb |
136 | =item ($signal_func, $signal_arg) = $async->signal_func |
105 | |
137 | |
106 | Returns the address of a function to call asynchronously. The function has |
138 | Returns the address of a function to call asynchronously. The function has |
107 | the following prototype and needs to be passed the specified C<$c_arg>, |
139 | the following prototype and needs to be passed the specified C<$c_arg>, |
108 | which is a C<void *> cast to C<IV>: |
140 | which is a C<void *> cast to C<IV>: |
109 | |
141 | |
… | |
… | |
111 | |
143 | |
112 | An example call would look like: |
144 | An example call would look like: |
113 | |
145 | |
114 | signal_func (signal_arg, 0); |
146 | signal_func (signal_arg, 0); |
115 | |
147 | |
116 | The function is safe toc all from within signal and thread contexts, at |
148 | The function is safe to call from within signal and thread contexts, at |
117 | any time. The specified C<value> is passed to both C and Perl callback. |
149 | any time. The specified C<value> is passed to both C and Perl callback. |
|
|
150 | |
|
|
151 | C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is |
|
|
152 | portable). |
118 | |
153 | |
119 | If the function is called while the Async::Interrupt object is already |
154 | If the function is called while the Async::Interrupt object is already |
120 | signaled but before the callbacks are being executed, then the stored |
155 | signaled but before the callbacks are being executed, then the stored |
121 | C<value> is being overwritten. Due to the asynchronous nature of the code, |
156 | C<value> is either the old or the new one. Due to the asynchronous |
122 | the C<value> can even be passed to two consecutive invocations of the |
157 | nature of the code, the C<value> can even be passed to two consecutive |
123 | callback. |
158 | invocations of the callback. |
124 | |
159 | |
125 | =item $async->signal ($value=0) |
160 | =item $async->signal ($value=0) |
126 | |
161 | |
127 | This signals the given async object from Perl code. Semi-obviously, this |
162 | This signals the given async object from Perl code. Semi-obviously, this |
128 | will instantly trigger the callback invocation. |
163 | will instantly trigger the callback invocation. |
129 | |
164 | |
|
|
165 | C<$value> must be in the valid range for a C<sig_atomic_t> (0..127 is |
|
|
166 | portable). |
|
|
167 | |
|
|
168 | =item $async->block |
|
|
169 | |
|
|
170 | Sometimes you need a "critical section" of code where |
|
|
171 | |
|
|
172 | =item $async->unblock |
|
|
173 | |
130 | =cut |
174 | =cut |
131 | |
175 | |
132 | 1; |
176 | 1; |
133 | |
177 | |
134 | =back |
178 | =back |
|
|
179 | |
|
|
180 | =head1 EXAMPLE |
|
|
181 | |
|
|
182 | #TODO |
|
|
183 | |
|
|
184 | =head1 IMPLEMENTATION DETAILS AND LIMITATIONS |
|
|
185 | |
|
|
186 | This module works by "hijacking" SIGKILL, which is guarenteed to be always |
|
|
187 | available in perl, but also cannot be caught, so is always available. |
|
|
188 | |
|
|
189 | Basically, this module fakes the receive of a SIGKILL signal and |
|
|
190 | then catches it. This makes normal signal handling slower (probably |
|
|
191 | unmeasurably), but has the advantage of not requiring a special runops nor |
|
|
192 | slowing down normal perl execution a bit. |
|
|
193 | |
|
|
194 | 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 |
|
|
196 | C<int>, so we can assume that this is quite portbale, at least w.r.t. |
|
|
197 | signals). |
135 | |
198 | |
136 | =head1 AUTHOR |
199 | =head1 AUTHOR |
137 | |
200 | |
138 | Marc Lehmann <schmorp@schmorp.de> |
201 | Marc Lehmann <schmorp@schmorp.de> |
139 | http://home.schmorp.de/ |
202 | http://home.schmorp.de/ |