view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$class->API_VERSION >= NEED_API_VERSION or
die "$class is too old for IO::Async $VERSION; we need API version >= ".NEED_API_VERSION.", it provides ".$class->API_VERSION."\n";
WATCHDOG_ENABLE and !$class->_CAN_WATCHDOG and
warn "$class cannot implement IO_ASYNC_WATCHDOG\n";
my $self = bless {
notifiers => {}, # {nkey} = notifier
iowatches => {}, # {fd} = [ $on_read_ready, $on_write_ready, $on_hangup ]
sigattaches => {}, # {sig} => \@callbacks
childmanager => undef,
childwatches => {}, # {pid} => $code
threadwatches => {}, # {tid} => $code
timequeue => undef,
deferrals => [],
os => {}, # A generic scratchpad for IO::Async::OS to store whatever it wants
}, $class;
# It's possible this is a specific subclass constructor. We still want the
# magic IO::Async::Loop->new constructor to yield this if it's the first
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
# These features aren't supposed to be "user visible", so if methods called
# on it carp or croak, the shortmess line ought to skip IO::Async::Loop and
# go on report its caller. To make this work, add the feature class to our
# @CARP_NOT list.
push our(@CARP_NOT), $classname;
return $classname->new( loop => $self );
}
=head2 attach_signal
$id = $loop->attach_signal( $signal, $code )
This method adds a new signal handler to watch the given signal. The same
signal can be attached to multiple times; its callback functions will all be
invoked, in no particular order.
The returned C<$id> value can be used to identify the signal handler in case
it needs to be removed by the C<detach_signal> method. Note that this value
may be an object reference, so if it is stored, it should be released after it
cancelled, so the object itself can be freed.
=over 8
=item $signal
The name of the signal to attach to. This should be a bare name like C<TERM>.
=item $code
A CODE reference to the handling callback.
=back
Attaching to C<SIGCHLD> is not recommended because of the way all child
processes use it to report their termination. Instead, the C<watch_child>
method should be used to watch for termination of a given child process. A
warning will be printed if C<SIGCHLD> is passed here, but in future versions
of L<IO::Async> this behaviour may be disallowed altogether.
See also L<POSIX> for the C<SIGI<name>> constants.
For a more flexible way to use signals from within Notifiers, see instead the
L<IO::Async::Signal> object.
=cut
sub attach_signal
{
my $self = shift;
my ( $signal, $code ) = @_;
HAVE_SIGNALS or croak "This OS cannot ->attach_signal";
if( $signal eq "CHLD" ) {
# We make special exception to allow $self->watch_child to do this
caller eq "IO::Async::Loop" or
carp "Attaching to SIGCHLD is not advised - use ->watch_child instead";
}
if( not $self->{sigattaches}->{$signal} ) {
my @attaches;
$self->watch_signal( $signal, sub {
foreach my $attachment ( @attaches ) {
$attachment->();
}
} );
$self->{sigattaches}->{$signal} = \@attaches;
}
push @{ $self->{sigattaches}->{$signal} }, $code;
return \$self->{sigattaches}->{$signal}->[-1];
}
=head2 detach_signal
$loop->detach_signal( $signal, $id )
Removes a previously-attached signal handler.
=over 8
=item $signal
The name of the signal to remove from. This should be a bare name like
C<TERM>.
=item $id
The value returned by the C<attach_signal> method.
=back
=cut
sub detach_signal
{
my $self = shift;
my ( $signal, $id ) = @_;
HAVE_SIGNALS or croak "This OS cannot ->detach_signal";
# Can't use grep because we have to preserve the addresses
my $attaches = $self->{sigattaches}->{$signal} or return;
for (my $i = 0; $i < @$attaches; ) {
$i++, next unless \$attaches->[$i] == $id;
splice @$attaches, $i, 1, ();
}
if( !@$attaches ) {
$self->unwatch_signal( $signal );
delete $self->{sigattaches}->{$signal};
}
}
=head2 later
$loop->later( $code )
Schedules a code reference to be invoked as soon as the current round of IO
operations is complete.
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
$self->__new_feature( "IO::Async::ChildManager" );
$childmanager->spawn_child( %params );
}
=head2 open_child
$pid = $loop->open_child( %params )
This creates a new child process to run the given code block or command, and
attaches filehandles to it that the parent will watch. This method is a light
wrapper around constructing a new L<IO::Async::Process> object, provided
largely for backward compatibility. New code ought to construct such an object
directly, as it may provide more features than are available here.
The C<%params> hash takes the following keys:
=over 8
=item command => ARRAY or STRING
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=item $code
A CODE reference to the handling callback.
=back
There can only be one callback per signal name. Registering a new one will
remove an existing one.
Applications should use a L<IO::Async::Signal> object, or call
C<attach_signal> instead of using this method.
This and C<unwatch_signal> are optional; a subclass may implement neither, or
both. If it implements neither then signal handling will be performed by the
base class using a self-connected pipe to interrupt the main IO blocking.
=cut
sub watch_signal
{
my $self = shift;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
sub watch_child
{
my $self = shift;
my ( $pid, $code ) = @_;
my $childwatches = $self->{childwatches};
croak "Already have a handler for $pid" if exists $childwatches->{$pid};
if( HAVE_SIGNALS and !$self->{childwatch_sigid} ) {
$self->{childwatch_sigid} = $self->attach_signal(
CHLD => sub { _reap_children( $childwatches ) }
);
# There's a chance the child has already exited
my $zid = waitpid( $pid, WNOHANG );
if( defined $zid and $zid > 0 ) {
my $exitstatus = $?;
$self->later( sub { $code->( $pid, $exitstatus ) } );
return;
}
local/lib/perl5/IO/Async/LoopTests.pm view on Meta::CPAN
is( $caught, 2, '$caught after second ->loop_once' );
is_oneref( $loop, '$loop has refcount 1 before unwatch_signal' );
$loop->unwatch_signal( 'TERM' );
is_oneref( $loop, '$loop has refcount 1 after unwatch_signal' );
my ( $cA, $cB );
my $idA = $loop->attach_signal( TERM => sub { $cA = 1 } );
my $idB = $loop->attach_signal( TERM => sub { $cB = 1 } );
is_oneref( $loop, '$loop has refcount 1 after 2 * attach_signal' );
kill SIGTERM, $$;
$loop->loop_once( 0.1 );
is( $cA, 1, '$cA after raise' );
is( $cB, 1, '$cB after raise' );
$loop->detach_signal( 'TERM', $idA );
local/lib/perl5/IO/Async/LoopTests.pm view on Meta::CPAN
kill SIGTERM, $$;
$loop->loop_once( 0.1 );
is( $cA, undef, '$cA after raise' );
is( $cB, 1, '$cB after raise' );
$loop->detach_signal( 'TERM', $idB );
ok( exception { $loop->attach_signal( 'this signal name does not exist', sub {} ) },
'Bad signal name fails' );
}
=head2 idle
Tests the Loop's support for idle handlers
=cut
use constant count_tests_idle => 11;
local/lib/perl5/IO/Async/Signal.pm view on Meta::CPAN
$self->SUPER::configure( %params );
}
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
$self->{cb} ||= $self->make_event_cb( '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};
}
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
In this example, the header is C<unpack()>ed first, to extract the body
length, and then the body is extracted. If the buffer does not have enough
data yet for a complete message then C<0> is returned, and the buffer is left
unmodified for next time. Only when there are enough bytes in total does it
use C<substr()> to remove them.
=head2 Dynamic replacement of C<on_read>
Consider the following protocol (inspired by IMAP), which consists of
C<\n>-terminated lines that may have an optional data block attached. The
presence of such a data block, as well as its size, is indicated by the line
prefix.
sub on_read
{
my $self = shift;
my ( $buffref, $eof ) = @_;
if( $$buffref =~ s/^DATA (\d+):(.*)\n// ) {
my $length = $1;
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
first argument specifies the message to display to the user (for
example, C<"Where do you keep your money?">). The second argument,
which is optional, specifies a default answer (for example,
C<"wallet">). The user will be asked the question once.
If C<prompt()> detects that it is not running interactively and there
is nothing on STDIN or if the PERL_MM_USE_DEFAULT environment variable
is set to true, the $default will be used without prompting.
To prevent automated processes from blocking, the user must either set
PERL_MM_USE_DEFAULT or attach something to STDIN (this can be a
pipe/file containing a scripted set of answers or /dev/null.)
If no $default is provided an empty string will be used instead. In
non-interactive mode, the absence of $default is an error (though
explicitly passing C<undef()> as the default is valid as of 0.27.)
This method may be called as a class or object method.
=item recommends()