--- cvsroot/Async-Interrupt/Interrupt.pm 2009/07/28 12:50:16 1.18 +++ cvsroot/Async-Interrupt/Interrupt.pm 2009/07/28 13:17:05 1.19 @@ -95,19 +95,19 @@ =head1 USAGE EXAMPLES -=head2 Async::Interrupt to implement race-free signal handling +=head2 Implementing race-free signal handling This example uses a single event pipe for all signals, and one -Async::Interrupt per signal. +Async::Interrupt per signal. This code is actually what the L +module uses itself when Async::Interrupt is available. -First, create the event pipe and hook it into the event loop (this code is -actually what L uses itself): +First, create the event pipe and hook it into the event loop $SIGPIPE = new Async::Interrupt::EventPipe; $SIGPIPE_W = AnyEvent->io ( fh => $SIGPIPE->fileno, poll => "r", - cb => \&_signal_check, + cb => \&_signal_check, # defined later ); Then, for each signal to hook, create an Async::Interrupt object. The @@ -117,8 +117,8 @@ my $interrupt = new Async::Interrupt cb => sub { undef $SIGNAL_RECEIVED{$signum} } - signal => $signal, - pipe => [$SIGPIPE_R->filenos], + signal => $signum, + pipe => [$SIGPIPE->filenos], pipe_autodrain => 0, ; @@ -137,7 +137,12 @@ } } +=head2 Interrupt perl from another thread +This example interrupts the Perl interpreter from another thread, via the +XS API. This is used by e.g. the L module. + +#TODO# =head1 THE Async::Interrupt CLASS @@ -151,10 +156,11 @@ BEGIN { # the next line forces initialisation of internal - # signal handling # variables + # signal handling variables, otherwise, PL_sig_pending + # etc. will be null pointers. $SIG{KILL} = sub { }; - our $VERSION = '0.6'; + our $VERSION = '1.0'; require XSLoader; XSLoader::load ("Async::Interrupt", $VERSION); @@ -187,7 +193,7 @@ If the callback should throw an exception, then it will be caught, and C<$Async::Interrupt::DIED> will be called with C<$@> containing -the exception. The default will simply C about the message and +the exception. The default will simply C about the message and continue. =item c_cb => [$c_func, $c_arg] @@ -231,6 +237,11 @@ Only one async can hook a given signal, and the signal will be restored to defaults when the Async::Interrupt object gets destroyed. +=item signal_hysteresis => $boolean + +Sets the initial signal hysteresis state, see the C +method, below. + =item pipe => [$fileno_or_fh_for_reading, $fileno_or_fh_for_writing] Specifies two file descriptors (or file handles) that should be signalled @@ -253,6 +264,10 @@ objects, you can use the C class to manage those. +=item pipe_autodrain => $boolean + +Sets the initial autodrain state, see the C method, below. + =back =cut @@ -260,7 +275,14 @@ sub new { my ($class, %arg) = @_; - bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}, $arg{var}), $class + my $self = bless \(_alloc $arg{cb}, @{$arg{c_cb}}[0,1], @{$arg{pipe}}[0,1], $arg{signal}, $arg{var}), $class; + + # urgs, reminds me of Event + for my $attr (qw(pipe_autodrain signal_hysteresis)) { + $self->$attr ($arg{$attr}) if exists $arg{$attr}; + } + + $self } =item ($signal_func, $signal_arg) = $async->signal_func