… | |
… | |
91 | I<running> interpreter, there is optional support for signalling a pipe |
91 | I<running> interpreter, there is optional support for signalling a pipe |
92 | - that means you can also wait for the pipe to become readable (e.g. via |
92 | - that means you can also wait for the pipe to become readable (e.g. via |
93 | L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a C<read> |
93 | L<EV> or L<AnyEvent>). This, of course, incurs the overhead of a C<read> |
94 | and C<write> syscall. |
94 | and C<write> syscall. |
95 | |
95 | |
|
|
96 | =head1 USAGE EXAMPLES |
|
|
97 | |
|
|
98 | =head2 Implementing race-free signal handling |
|
|
99 | |
|
|
100 | This example uses a single event pipe for all signals, and one |
|
|
101 | Async::Interrupt per signal. This code is actually what the L<AnyEvent> |
|
|
102 | module uses itself when Async::Interrupt is available. |
|
|
103 | |
|
|
104 | First, create the event pipe and hook it into the event loop |
|
|
105 | |
|
|
106 | $SIGPIPE = new Async::Interrupt::EventPipe; |
|
|
107 | $SIGPIPE_W = AnyEvent->io ( |
|
|
108 | fh => $SIGPIPE->fileno, |
|
|
109 | poll => "r", |
|
|
110 | cb => \&_signal_check, # defined later |
|
|
111 | ); |
|
|
112 | |
|
|
113 | Then, for each signal to hook, create an Async::Interrupt object. The |
|
|
114 | callback just sets a global variable, as we are only interested in |
|
|
115 | synchronous signals (i.e. when the event loop polls), which is why the |
|
|
116 | pipe draining is not done automatically. |
|
|
117 | |
|
|
118 | my $interrupt = new Async::Interrupt |
|
|
119 | cb => sub { undef $SIGNAL_RECEIVED{$signum} } |
|
|
120 | signal => $signum, |
|
|
121 | pipe => [$SIGPIPE->filenos], |
|
|
122 | pipe_autodrain => 0, |
|
|
123 | ; |
|
|
124 | |
|
|
125 | Finally, the I/O callback for the event pipe handles the signals: |
|
|
126 | |
|
|
127 | sub _signal_check { |
|
|
128 | # drain the pipe first |
|
|
129 | $SIGPIPE->drain; |
|
|
130 | |
|
|
131 | # two loops, just to be sure |
|
|
132 | while (%SIGNAL_RECEIVED) { |
|
|
133 | for (keys %SIGNAL_RECEIVED) { |
|
|
134 | delete $SIGNAL_RECEIVED{$_}; |
|
|
135 | warn "signal $_ received\n"; |
|
|
136 | } |
|
|
137 | } |
|
|
138 | } |
|
|
139 | |
|
|
140 | =head2 Interrupt perl from another thread |
|
|
141 | |
|
|
142 | This example interrupts the Perl interpreter from another thread, via the |
|
|
143 | XS API. This is used by e.g. the L<EV::Loop::Async> module. |
|
|
144 | |
|
|
145 | #TODO# |
|
|
146 | |
96 | =head1 THE Async::Interrupt CLASS |
147 | =head1 THE Async::Interrupt CLASS |
97 | |
148 | |
98 | =over 4 |
149 | =over 4 |
99 | |
150 | |
100 | =cut |
151 | =cut |
… | |
… | |
103 | |
154 | |
104 | use common::sense; |
155 | use common::sense; |
105 | |
156 | |
106 | BEGIN { |
157 | BEGIN { |
107 | # the next line forces initialisation of internal |
158 | # the next line forces initialisation of internal |
108 | # signal handling # variables |
159 | # signal handling variables, otherwise, PL_sig_pending |
|
|
160 | # etc. will be null pointers. |
109 | $SIG{KILL} = sub { }; |
161 | $SIG{KILL} = sub { }; |
110 | |
162 | |
111 | our $VERSION = '0.6'; |
163 | our $VERSION = '1.0'; |
112 | |
164 | |
113 | require XSLoader; |
165 | require XSLoader; |
114 | XSLoader::load ("Async::Interrupt", $VERSION); |
166 | XSLoader::load ("Async::Interrupt", $VERSION); |
115 | } |
167 | } |
116 | |
168 | |
… | |
… | |
139 | The exceptions are C<$!> and C<$@>, which are saved and restored by |
191 | The exceptions are C<$!> and C<$@>, which are saved and restored by |
140 | Async::Interrupt. |
192 | Async::Interrupt. |
141 | |
193 | |
142 | If the callback should throw an exception, then it will be caught, |
194 | If the callback should throw an exception, then it will be caught, |
143 | and C<$Async::Interrupt::DIED> will be called with C<$@> containing |
195 | and C<$Async::Interrupt::DIED> will be called with C<$@> containing |
144 | the exception. The default will simply C<warn> about the message and |
196 | the exception. The default will simply C<warn> about the message and |
145 | continue. |
197 | continue. |
146 | |
198 | |
147 | =item c_cb => [$c_func, $c_arg] |
199 | =item c_cb => [$c_func, $c_arg] |
148 | |
200 | |
149 | Registers a C callback the be invoked whenever the async interrupt is |
201 | Registers a C callback the be invoked whenever the async interrupt is |
… | |
… | |
183 | the given signal is caught by the process. |
235 | the given signal is caught by the process. |
184 | |
236 | |
185 | Only one async can hook a given signal, and the signal will be restored to |
237 | Only one async can hook a given signal, and the signal will be restored to |
186 | defaults when the Async::Interrupt object gets destroyed. |
238 | defaults when the Async::Interrupt object gets destroyed. |
187 | |
239 | |
|
|
240 | =item signal_hysteresis => $boolean |
|
|
241 | |
|
|
242 | Sets the initial signal hysteresis state, see the C<signal_hysteresis> |
|
|
243 | method, below. |
|
|
244 | |
188 | =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] |
245 | =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] |
189 | |
246 | |
190 | Specifies two file descriptors (or file handles) that should be signalled |
247 | Specifies two file descriptors (or file handles) that should be signalled |
191 | whenever the async interrupt is signalled. This means a single octet will |
248 | whenever the async interrupt is signalled. This means a single octet will |
192 | be written to it, and before the callback is being invoked, it will be |
249 | be written to it, and before the callback is being invoked, it will be |
… | |
… | |
205 | |
262 | |
206 | If you want to share a single event pipe between multiple Async::Interrupt |
263 | If you want to share a single event pipe between multiple Async::Interrupt |
207 | objects, you can use the C<Async::Interrupt::EventPipe> class to manage |
264 | objects, you can use the C<Async::Interrupt::EventPipe> class to manage |
208 | those. |
265 | those. |
209 | |
266 | |
|
|
267 | =item pipe_autodrain => $boolean |
|
|
268 | |
|
|
269 | Sets the initial autodrain state, see the C<pipe_autodrain> method, below. |
|
|
270 | |
210 | =back |
271 | =back |
211 | |
272 | |
212 | =cut |
273 | =cut |
213 | |
274 | |
214 | sub new { |
275 | sub new { |
215 | my ($class, %arg) = @_; |
276 | my ($class, %arg) = @_; |
216 | |
277 | |
217 | bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}, $arg{var}), $class |
278 | my $self = bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}, $arg{var}), $class; |
|
|
279 | |
|
|
280 | # urgs, reminds me of Event |
|
|
281 | for my $attr (qw(pipe_autodrain signal_hysteresis)) { |
|
|
282 | $self->$attr ($arg{$attr}) if exists $arg{$attr}; |
|
|
283 | } |
|
|
284 | |
|
|
285 | $self |
218 | } |
286 | } |
219 | |
287 | |
220 | =item ($signal_func, $signal_arg) = $async->signal_func |
288 | =item ($signal_func, $signal_arg) = $async->signal_func |
221 | |
289 | |
222 | Returns the address of a function to call asynchronously. The function |
290 | Returns the address of a function to call asynchronously. The function |
… | |
… | |
376 | This only works when the pipe was created by Async::Interrupt. |
444 | This only works when the pipe was created by Async::Interrupt. |
377 | |
445 | |
378 | Async::Interrupt ensures that the reading file descriptor does not change |
446 | Async::Interrupt ensures that the reading file descriptor does not change |
379 | it's value. |
447 | it's value. |
380 | |
448 | |
|
|
449 | =item $signum = Async::Interrupt::sig2num $signame_or_number |
|
|
450 | |
|
|
451 | =item $signame = Async::Interrupt::sig2name $signame_or_number |
|
|
452 | |
|
|
453 | These two convenience functions simply convert a signal name or number to |
|
|
454 | the corresponding name or number. They are not used by this module and |
|
|
455 | exist just because perl doesn't have a nice way to do this on its own. |
|
|
456 | |
|
|
457 | They will return C<undef> on illegal names or numbers. |
|
|
458 | |
381 | =back |
459 | =back |
382 | |
460 | |
383 | =head1 THE Async::Interrupt::EventPipe CLASS |
461 | =head1 THE Async::Interrupt::EventPipe CLASS |
384 | |
462 | |
385 | Pipes are the predominent utility to make asynchronous signals |
463 | Pipes are the predominent utility to make asynchronous signals |