1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
# (C) Paul Evans, 2009 -- leonerd@leonerd.org.uk
package IO::Async::Signal;
use strict;
use warnings;
use base qw( IO::Async::Notifier );
our $VERSION = '0.29';
use Carp;
=head1 NAME
C<IO::Async::Signal> - event callback on receipt of a POSIX signal
=head1 SYNOPSIS
use IO::Async::Signal;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new();
my $signal = IO::Async::Signal->new(
name => "HUP",
on_receipt => sub {
print "I caught SIGHUP\n";
},
);
$loop->add( $signal );
$loop->loop_forever;
=head1 DESCRIPTION
This module provides a class of C<IO::Async::Notifier> which invokes its
callback when a particular POSIX signal is received.
Multiple objects can be added to a C<Loop> that all watch for the same signal.
The callback functions will all be invoked, in no particular order.
This object may be used in one of two ways; with a callback function, or as a
base class.
=over 4
=item Callbacks
If the C<on_receipt> key is supplied to the constructor, it should contain a
CODE reference to a callback function to be invoked when the signal is received.
$on_receipt->( $self )
=item Base Class
If a subclass is built, then it can override the C<on_receipt> method.
$self->on_receipt()
=back
=cut
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=over 8
=item name => STRING
The name of the signal to watch. This should be a bare name like C<TERM>. Can
only be given at construction time.
=item on_receipt => CODE
CODE reference to callback to invoke when the signal is received. If not
supplied, the subclass method will be called instead.
=back
Once constructed, the C<Signal> will need to be added to the C<Loop> before it
will work.
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
my $name = delete $params->{name} or croak "Expected 'name'";
$name =~ s/^SIG//; # Trim a leading "SIG"
$self->{name} = $name;
$self->SUPER::_init( $params );
}
sub configure
{
my $self = shift;
my %params = @_;
if( exists $params{on_receipt} ) {
$self->{on_receipt} = delete $params{on_receipt};
undef $self->{cb}; # Will be lazily constructed when needed
if( my $loop = $self->get_loop ) {
$self->_remove_from_loop( $loop );
$self->_add_to_loop( $loop );
}
}
if( !$self->{on_receipt} and !$self->can( 'on_receipt' ) ) {
croak 'Expected either a on_receipt callback or an ->on_receipt method';
}
$self->SUPER::configure( %params );
}
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
if( !$self->{cb} ) {
if( $self->{on_receipt} ) {
$self->{cb} = $self->_capture_weakself( $self->{on_receipt} );
}
else {
$self->{cb} = $self->_capture_weakself( 'on_receipt' );
}
}
$self->{id} = $loop->attach_signal( $self->{name}, $self->{cb} );
}
sub _remove_from_loop
{
my $self = shift;
my ( $loop ) = @_;
$loop->detach_signal( $self->{name}, $self->{id} );
undef $self->{id};
}
# Keep perl happy; keep Britain tidy
1;
__END__
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
|