view release on metacpan or search on metacpan
local/lib/perl5/Future.pm view on Meta::CPAN
may be useful to provide C<Future> subclasses with event systems, or similar.
Each method that returns a new future object will use the invocant to
construct its return value. If the constructor needs to perform per-instance
setup it can override the C<new> method, and take context from the given
instance.
sub new
{
my $proto = shift;
my $self = $proto->SUPER::new;
if( ref $proto ) {
# Prototype was an instance
}
else {
# Prototype was a class
}
return $self;
}
local/lib/perl5/IO/Async/Channel.pm view on Meta::CPAN
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
defined $params->{codec} or $params->{codec} = "Storable";
$self->SUPER::_init( $params );
}
sub configure
{
my $self = shift;
my %params = @_;
foreach (qw( on_recv on_eof )) {
next unless exists $params{$_};
$self->{mode} and $self->{mode} eq "async" or
local/lib/perl5/IO/Async/Channel.pm view on Meta::CPAN
$self->{$_} = delete $params{$_};
$self->_build_stream;
}
if( my $codec = delete $params{codec} ) {
@{ $self }{qw( encode decode )} = (
$self->can( "_make_codec_$codec" ) or croak "Unrecognised codec name '$codec'"
)->();
}
$self->SUPER::configure( %params );
}
sub _make_codec_Storable
{
require Storable;
return
\&Storable::freeze,
\&Storable::thaw;
}
local/lib/perl5/IO/Async/File.pm view on Meta::CPAN
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
$params->{interval} ||= 2;
$self->SUPER::_init( $params );
$self->start;
}
sub configure
{
my $self = shift;
my %params = @_;
if( exists $params{filename} ) {
local/lib/perl5/IO/Async/File.pm view on Meta::CPAN
}
elsif( exists $params{handle} ) {
$self->{handle} = delete $params{handle};
$self->{last_stat} = stat $self->{handle};
}
foreach ( @STATS, "devino", "stat" ) {
$self->{"on_${_}_changed"} = delete $params{"on_${_}_changed"} if exists $params{"on_${_}_changed"};
}
$self->SUPER::configure( %params );
}
sub _add_to_loop
{
my $self = shift;
if( !defined $self->{filename} and !defined $self->{handle} ) {
croak "IO::Async::File needs either a filename or a handle";
}
return $self->SUPER::_add_to_loop( @_ );
}
sub _reopen_file
{
my $self = shift;
my $path = $self->{filename};
open $self->{handle}, "<", $path or croak "Cannot open $path for reading - $!";
local/lib/perl5/IO/Async/FileStream.pm view on Meta::CPAN
This method may be useful to skip initial content in the file, if the object
should only respond to new content added after it was created.
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
$self->SUPER::_init( $params );
$params->{close_on_read_eof} = 0;
$self->{last_size} = undef;
$self->add_child( $self->{file} = IO::Async::File->new(
on_devino_changed => $self->_replace_weakself( 'on_devino_changed' ),
on_size_changed => $self->_replace_weakself( 'on_size_changed' ),
) );
}
local/lib/perl5/IO/Async/FileStream.pm view on Meta::CPAN
elsif( exists $params{handle} or exists $params{read_handle} ) {
my $handle = delete $params{handle};
defined $handle or $handle = delete $params{read_handle};
$self->{file}->configure( handle => $handle );
$params{read_handle} = $self->{file}->handle;
}
croak "Cannot have a write_handle in a ".ref($self) if defined $params{write_handle};
$self->SUPER::configure( %params );
if( $self->read_handle and !defined $self->{last_size} ) {
my $size = (stat $self->read_handle)[7];
$self->{last_size} = $size;
local $self->{running_initial} = 1;
$self->maybe_invoke_event( on_initial => $size );
}
}
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
=head2 setup => ARRAY
Optional array reference. Specifies the C<setup> key to pass to the underlying
L<IO::Async::Process> when setting up new worker processes.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{min_workers} = 1;
$self->{max_workers} = 8;
$self->{workers} = {}; # {$id} => IaFunction:Worker
$self->{pending_queue} = [];
}
sub configure
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
$self->{$_} = delete $params{$_} if exists $params{$_};
# TODO: something about retuning
}
my $need_restart;
foreach (qw( init_code code setup )) {
$need_restart++, $self->{$_} = delete $params{$_} if exists $params{$_};
}
$self->SUPER::configure( %params );
if( $need_restart and $self->loop ) {
$self->stop;
$self->start;
}
}
sub _add_to_loop
{
my $self = shift;
$self->SUPER::_add_to_loop( @_ );
$self->start;
}
sub _remove_from_loop
{
my $self = shift;
$self->stop;
$self->SUPER::_remove_from_loop( @_ );
}
=head1 METHODS
The following methods documented with a trailing call to C<< ->get >> return
L<Future> instances.
=cut
=head2 start
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
# Presume that $@ is an ARRAYref of error results
$ret_channel->send( [ e => @{ $@ } ] );
}
else {
chomp( my $e = "$@" );
$ret_channel->send( [ e => $e, error => ] );
}
}
};
my $worker = $class->SUPER::new(
%params,
channels_in => [ $arg_channel ],
channels_out => [ $ret_channel ],
);
$worker->{arg_channel} = $arg_channel;
$worker->{ret_channel} = $ret_channel;
return $worker;
}
sub configure
{
my $self = shift;
my %params = @_;
exists $params{$_} and $self->{$_} = delete $params{$_} for qw( exit_on_die max_calls );
$self->SUPER::configure( %params );
}
sub stop
{
my $worker = shift;
$worker->{arg_channel}->close;
if( my $function = $worker->parent ) {
delete $function->{workers}{$worker->id};
local/lib/perl5/IO/Async/Future.pm view on Meta::CPAN
$future = $loop->timeout_future( %args )
Returns a new Future that will become failed at a given time.
=cut
sub new
{
my $proto = shift;
my $self = $proto->SUPER::new;
if( ref $proto ) {
$self->{loop} = $proto->{loop};
}
else {
$self->{loop} = shift;
}
return $self;
}
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
}
if( exists $params{want_readready} ) {
$self->want_readready( delete $params{want_readready} );
}
if( exists $params{want_writeready} ) {
$self->want_writeready( delete $params{want_writeready} );
}
$self->SUPER::configure( %params );
}
# We'll be calling these any of three times
# adding to/removing from loop
# caller en/disables readiness checking
# changing filehandle
sub _watch_read
{
my $self = shift;
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
my $self = shift;
my ( $loop ) = @_;
$self->_watch_read(0);
$self->_watch_write(0);
}
sub notifier_name
{
my $self = shift;
if( length( my $name = $self->SUPER::notifier_name ) ) {
return $name;
}
my $r = $self->read_fileno;
my $w = $self->write_fileno;
return "rw=$r" if defined $r and defined $w and $r == $w;
return "r=$r,w=$w" if defined $r and defined $w;
return "r=$r" if defined $r;
return "w=$w" if defined $w;
return "no";
local/lib/perl5/IO/Async/Internals/TimeQueue.pm view on Meta::CPAN
use strict;
our @ISA = qw( Heap::Elem );
sub new
{
my $self = shift;
my $class = ref $self || $self;
my ( $time, $code ) = @_;
my $new = $class->SUPER::new(
time => $time,
code => $code,
);
return $new;
}
sub time
{
my $self = shift;
local/lib/perl5/IO/Async/Listener.pm view on Meta::CPAN
It is invoked with the listening socket as its its argument, and optionally
an L<IO::Async::Handle> instance as a named parameter, and is expected to
return a C<Future> that will eventually yield the newly-accepted socket or
handle instance, if such was provided.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{acceptor} = "_accept";
}
my @acceptor_events = qw( on_accept on_stream on_socket );
sub configure
{
my $self = shift;
my %params = @_;
local/lib/perl5/IO/Async/Listener.pm view on Meta::CPAN
# So now we know it's at least some kind of socket. Is it listening?
# SO_ACCEPTCONN would tell us, but not all OSes implement it. Since it's
# only a best-effort sanity check, we won't mind if the OS doesn't.
my $acceptconn = getsockopt( $handle, SOL_SOCKET, SO_ACCEPTCONN );
!defined $acceptconn or unpack( "I", $acceptconn ) or croak "Socket is not accepting connections";
# This is a bit naughty but hopefully nobody will mind...
bless $handle, "IO::Socket" if ref( $handle ) eq "GLOB";
$self->SUPER::configure( read_handle => $handle );
}
elsif( exists $params{handle} ) {
delete $params{handle};
$self->SUPER::configure( read_handle => undef );
}
unless( grep $self->can_event( $_ ), @acceptor_events ) {
croak "Expected to be able to 'on_accept', 'on_stream' or 'on_socket'";
}
foreach (qw( acceptor handle_constructor handle_class )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
}
=head2 configure
$notifier->configure( %params )
This method is called by the constructor to set the initial values of named
parameters, and by users of the object to adjust the values once constructed.
This method should C<delete> from the C<%params> hash any keys it has dealt
with, then pass the remaining ones to the C<SUPER::configure>. The base
class implementation will throw an exception if there are any unrecognised
keys remaining.
=cut
=head2 configure_unknown
$notifier->configure_unknown( %params )
This method is called by the base class C<configure> method, for any remaining
local/lib/perl5/IO/Async/OS/linux.pm view on Meta::CPAN
# Try to use /proc/pid/fd to get the list of actually-open file descriptors
# for our process. Saves a bit of time when running with high ulimit -n /
# fileno counts.
sub potentially_open_fds
{
my $class = shift;
opendir my $fd_path, "/proc/$$/fd" or do {
warn "Cannot open /proc/$$/fd, falling back to generic method - $!";
return $class->SUPER::potentially_open_fds
};
# Skip ., .., our directory handle itself and any other cruft
# except fileno() isn't available for the handle so we'll
# end up with that in the output anyway. As long as we're
# called just before the relevant close() loop, this
# should be harmless enough.
my @fd = map { m/^([0-9]+)$/ ? $1 : () } readdir $fd_path;
closedir $fd_path;
local/lib/perl5/IO/Async/PID.pm view on Meta::CPAN
$self->{on_exit} = delete $params{on_exit};
undef $self->{cb};
if( my $loop = $self->loop ) {
$self->_remove_from_loop( $loop );
$self->_add_to_loop( $loop );
}
}
$self->SUPER::configure( %params );
}
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
$self->pid or croak "Require a 'pid' in $self";
$self->SUPER::_add_to_loop( @_ );
# on_exit continuation gets passed PID value; need to replace that with
# $self
$self->{cb} ||= $self->_replace_weakself( sub {
my $self = shift or return;
my ( $exitcode ) = @_;
$self->invoke_event( on_exit => $exitcode );
# Since this is a oneshot, we'll have to remove it from the loop or
local/lib/perl5/IO/Async/PID.pm view on Meta::CPAN
{
my $self = shift;
my ( $loop ) = @_;
$loop->unwatch_child( $self->pid );
}
sub notifier_name
{
my $self = shift;
if( length( my $name = $self->SUPER::notifier_name ) ) {
return $name;
}
return $self->{pid};
}
=head1 METHODS
=cut
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
Constructs a new C<IO::Async::Process> object and returns it.
Once constructed, the C<Process> will need to be added to the C<Loop> before
the child process is started.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{to_close} = {};
$self->{finish_futures} = [];
}
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=head2 on_finish => CODE
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
$self->configure_fd( 2, %{ delete $setup_params{stderr} } ) if $setup_params{stderr};
$self->configure_fd( 'io', %{ delete $setup_params{stdio} } ) if $setup_params{stdio};
# All the rest are fd\d+
foreach ( keys %setup_params ) {
my ( $fd ) = m/^fd(\d+)$/ or croak "Expected 'fd\\d+'";
$self->configure_fd( $fd, %{ $setup_params{$_} } );
}
$self->SUPER::configure( %params );
}
# These are from the perspective of the parent
use constant FD_VIA_PIPEREAD => 1;
use constant FD_VIA_PIPEWRITE => 2;
use constant FD_VIA_PIPERDWR => 3; # Only valid for stdio pseudo-fd
use constant FD_VIA_SOCKETPAIR => 4;
my %via_names = (
pipe_read => FD_VIA_PIPEREAD,
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
on_exit => $self->_capture_weakself( sub {
( my $self, undef, $exitcode, $dollarbang, $dollarat ) = @_;
$self->debug_printf( "EXIT status=0x%04x", $exitcode ) if $self;
$exit_future->done unless $exit_future->is_cancelled;
} ),
);
$self->{running} = 1;
$self->SUPER::_add_to_loop( @_ );
$_->close for values %{ delete $self->{to_close} };
my $is_code = defined $self->{code};
$self->{finish_future} = Future->needs_all( @$finish_futures )
->on_done( $self->_capture_weakself( sub {
my $self = shift or return;
$self->{exitcode} = $exitcode;
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
sub DESTROY
{
my $self = shift;
$self->{finish_future}->cancel if $self->{finish_future};
}
sub notifier_name
{
my $self = shift;
if( length( my $name = $self->SUPER::notifier_name ) ) {
return $name;
}
return "nopid" unless my $pid = $self->pid;
return "[$pid]" unless $self->is_running;
return "$pid";
}
=head1 METHODS
local/lib/perl5/IO/Async/Protocol.pm view on Meta::CPAN
$self->{transport} = $transport;
if( $transport ) {
$self->setup_transport( $self->transport );
$self->add_child( $self->transport );
}
}
$self->SUPER::configure( %params );
}
=head1 METHODS
=cut
=head2 transport
$transport = $protocol->transport
local/lib/perl5/IO/Async/Protocol/LineStream.pm view on Meta::CPAN
=head2 on_read_line => CODE
CODE reference for the C<on_read_line> event.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init;
$self->{eol} = "\x0d\x0a";
$self->{eol_pattern} = qr/\x0d?\x0a/;
}
sub configure
{
my $self = shift;
my %params = @_;
foreach (qw( on_read_line )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
$self->SUPER::configure( %params );
}
sub on_read
{
my $self = shift;
my ( $buffref, $eof ) = @_;
# Easiest to run each event individually, in case it returns a CODE ref
$$buffref =~ s/^(.*?)$self->{eol_pattern}// or return 0;
local/lib/perl5/IO/Async/Protocol/Stream.pm view on Meta::CPAN
for (qw( on_read on_read_eof on_write_eof )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
if( !exists $params{transport} and my $handle = delete $params{handle} ) {
require IO::Async::Stream;
$params{transport} = IO::Async::Stream->new( handle => $handle );
}
$self->SUPER::configure( %params );
if( $self->loop ) {
$self->can_event( "on_read" ) or
croak 'Expected either an on_read callback or to be able to ->on_read';
}
}
sub _add_to_loop
{
my $self = shift;
$self->can_event( "on_read" ) or
croak 'Expected either an on_read callback or to be able to ->on_read';
}
sub setup_transport
{
my $self = shift;
my ( $transport ) = @_;
$self->SUPER::setup_transport( $transport );
$transport->configure(
on_read => $self->_replace_weakself( sub {
my $self = shift or return;
$self->invoke_event( on_read => @_ );
} ),
on_read_eof => $self->_replace_weakself( sub {
my $self = shift or return;
$self->maybe_invoke_event( on_read_eof => @_ );
} ),
local/lib/perl5/IO/Async/Protocol/Stream.pm view on Meta::CPAN
sub teardown_transport
{
my $self = shift;
my ( $transport ) = @_;
$transport->configure(
on_read => undef,
);
$self->SUPER::teardown_transport( $transport );
}
=head1 METHODS
=cut
=head2 write
$protocol->write( $data )
local/lib/perl5/IO/Async/Protocol/Stream.pm view on Meta::CPAN
Sets up a connection to a peer, and configures the underlying C<transport> for
the Protocol. Calls L<IO::Async::Protocol> C<connect> with C<socktype> set to
C<"stream">.
=cut
sub connect
{
my $self = shift;
$self->SUPER::connect(
@_,
socktype => "stream",
);
}
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
local/lib/perl5/IO/Async/Resolver.pm view on Meta::CPAN
is set to a default of 30 seconds, and C<min_workers> is set to 0. This
ensures that there are no spare processes sitting idle during the common case
of no outstanding requests.
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
$self->SUPER::_init( @_ );
$params->{code} = sub {
my ( $type, $timeout, @data ) = @_;
if( my $code = $METHODS{$type} ) {
local $SIG{ALRM} = sub { die "Timed out\n" };
alarm( $timeout );
my @ret = eval { $code->( @data ) };
alarm( 0 );
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
IO::Async::OS->HAVE_THREADS ? "thread" :
die "No viable Routine models";
sub _init
{
my $self = shift;
my ( $params ) = @_;
$params->{model} ||= $ENV{IO_ASYNC_ROUTINE_MODEL} || PREFERRED_MODEL;
$self->SUPER::_init( @_ );
}
sub configure
{
my $self = shift;
my %params = @_;
# TODO: Can only reconfigure when not running
foreach (qw( channels_in channels_out code setup on_finish on_return on_die )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
local/lib/perl5/IO/Async/Routine.pm view on Meta::CPAN
croak "Expected 'model' to be either 'fork' or 'thread'";
$model eq "fork" and !IO::Async::OS->HAVE_POSIX_FORK and
croak "Cannot use 'fork' model as fork() is not available";
$model eq "thread" and !IO::Async::OS->HAVE_THREADS and
croak "Cannot use 'thread' model as threads are not available";
$self->{model} = $model;
}
$self->SUPER::configure( %params );
}
sub _add_to_loop
{
my $self = shift;
my ( $loop ) = @_;
$self->SUPER::_add_to_loop( $loop );
return $self->_setup_fork if $self->{model} eq "fork";
return $self->_setup_thread if $self->{model} eq "thread";
die "TODO: unrecognised Routine model $self->{model}";
}
sub _setup_fork
{
my $self = shift;
local/lib/perl5/IO/Async/Signal.pm view on Meta::CPAN
{
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};
local/lib/perl5/IO/Async/Signal.pm view on Meta::CPAN
if( my $loop = $self->loop ) {
$self->_remove_from_loop( $loop );
$self->_add_to_loop( $loop );
}
}
unless( $self->can_event( '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 ) = @_;
$self->{cb} ||= $self->make_event_cb( 'on_receipt' );
$self->{id} = $loop->attach_signal( $self->{name}, $self->{cb} );
local/lib/perl5/IO/Async/Signal.pm view on Meta::CPAN
my $self = shift;
my ( $loop ) = @_;
$loop->detach_signal( $self->{name}, $self->{id} );
undef $self->{id};
}
sub notifier_name
{
my $self = shift;
if( length( my $name = $self->SUPER::notifier_name ) ) {
return $name;
}
return $self->{name};
}
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
local/lib/perl5/IO/Async/Socket.pm view on Meta::CPAN
Optional. Invoked when the sending data buffer becomes empty.
=cut
sub _init
{
my $self = shift;
$self->{recv_len} = 65536;
$self->SUPER::_init( @_ );
}
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=head2 read_handle => IO
The IO handle to receive from. Must implement C<fileno> and C<recv> methods.
local/lib/perl5/IO/Async/Socket.pm view on Meta::CPAN
sub configure
{
my $self = shift;
my %params = @_;
for (qw( on_recv on_outgoing_empty on_recv_error on_send_error
recv_len recv_all send_all autoflush )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
$self->SUPER::configure( %params );
if( $self->loop and defined $self->read_handle ) {
$self->can_event( "on_recv" ) or
croak 'Expected either an on_recv callback or to be able to ->on_recv';
}
}
sub _add_to_loop
{
my $self = shift;
if( defined $self->read_handle ) {
$self->can_event( "on_recv" ) or
croak 'Expected either an on_recv callback or to be able to ->on_recv';
}
$self->SUPER::_add_to_loop( @_ );
}
=head1 METHODS
=cut
=head2 send
$socket->send( $data, $flags, $addr )
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
# TODO: reassert levels if we've moved them
}
if( exists $params{encoding} ) {
my $encoding = delete $params{encoding};
my $obj = find_encoding( $encoding );
defined $obj or croak "Cannot handle an encoding of '$encoding'";
$self->{encoding} = $obj;
}
$self->SUPER::configure( %params );
if( $self->loop and $self->read_handle ) {
$self->can_event( "on_read" ) or
croak 'Expected either an on_read callback or to be able to ->on_read';
}
}
sub _add_to_loop
{
my $self = shift;
if( defined $self->read_handle ) {
$self->can_event( "on_read" ) or
croak 'Expected either an on_read callback or to be able to ->on_read';
}
$self->SUPER::_add_to_loop( @_ );
if( !$self->_is_empty ) {
$self->want_writeready_for_write( 1 );
}
}
=head1 METHODS
The following methods documented with a trailing call to C<< ->get >> return
L<Future> instances.
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
Because of this deferred nature, it may not be suitable for error handling.
See instead the C<close_now> method.
=cut
sub close_when_empty
{
my $self = shift;
return $self->SUPER::close if $self->_is_empty;
$self->{stream_closing} = 1;
}
=head2 close_now
$stream->close_now
This method immediately closes the underlying IO handles and removes the
stream from the containing loop. It will not wait to flush the remaining data
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
{
my $self = shift;
foreach ( @{ $self->{writequeue} } ) {
$_->on_error->( "stream closing" ) if $_->on_error;
}
undef @{ $self->{writequeue} };
undef $self->{stream_closing};
$self->SUPER::close;
}
=head2 is_read_eof
=head2 is_write_eof
$eof = $stream->is_read_eof
$eof = $stream->is_write_eof
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
A convenient wrapper for calling the C<connect> method on the underlying
L<IO::Async::Loop> object, passing the C<socktype> hint as C<stream> if not
otherwise supplied.
=cut
sub connect
{
my $self = shift;
return $self->SUPER::connect( socktype => "stream", @_ );
}
=head1 DEBUGGING FLAGS
The following flags in C<IO_ASYNC_DEBUG_FLAGS> enable extra logging:
=over 4
=item C<Sr>
local/lib/perl5/IO/Async/Timer.pm view on Meta::CPAN
my %args = @_;
if( my $mode = delete $args{mode} ) {
# Might define some other modes later
$mode eq "countdown" or croak "Expected 'mode' to be 'countdown'";
require IO::Async::Timer::Countdown;
return IO::Async::Timer::Countdown->new( %args );
}
return $class->SUPER::new( %args );
}
sub _add_to_loop
{
my $self = shift;
$self->start if delete $self->{pending};
}
sub _remove_from_loop
{
local/lib/perl5/IO/Async/Timer/Absolute.pm view on Meta::CPAN
$self->{time} = $time;
$self->start if !$self->is_running;
}
unless( $self->can_event( 'on_expire' ) ) {
croak 'Expected either a on_expire callback or an ->on_expire method';
}
$self->SUPER::configure( %params );
}
sub _make_cb
{
my $self = shift;
return $self->_capture_weakself( sub {
my $self = shift or return;
undef $self->{id};
local/lib/perl5/IO/Async/Timer/Countdown.pm view on Meta::CPAN
my $delay = delete $params{delay};
$delay >= 0 or croak "Expected a 'delay' as a non-negative number";
$self->{delay} = $delay;
}
unless( $self->can_event( 'on_expire' ) ) {
croak 'Expected either a on_expire callback or an ->on_expire method';
}
$self->SUPER::configure( %params );
}
=head1 METHODS
=cut
=head2 is_expired
$expired = $timer->is_expired
local/lib/perl5/IO/Async/Timer/Periodic.pm view on Meta::CPAN
multiples/fractions of it.
Once constructed, the timer object will need to be added to the C<Loop> before
it will work. It will also need to be started by the C<start> method.
=cut
sub _init
{
my $self = shift;
$self->SUPER::_init( @_ );
$self->{reschedule} = "hard";
}
sub configure
{
my $self = shift;
my %params = @_;
if( exists $params{on_tick} ) {
local/lib/perl5/IO/Async/Timer/Periodic.pm view on Meta::CPAN
grep { $_ eq $resched } qw( hard skip drift ) or
croak "Expected 'reschedule' to be one of hard, skip, drift";
$self->{reschedule} = $resched;
}
unless( $self->can_event( 'on_tick' ) ) {
croak 'Expected either a on_tick callback or an ->on_tick method';
}
$self->SUPER::configure( %params );
}
sub _reschedule
{
my $self = shift;
my $now = $self->loop->time;
my $resched = $self->{reschedule};
my $next_interval = $self->{is_first} && defined $self->{first_interval}
local/lib/perl5/IO/Async/Timer/Periodic.pm view on Meta::CPAN
elsif( $resched eq "skip" ) {
# How many ticks are needed?
my $ticks = POSIX::ceil( $now - $self->{next_time} );
# $self->{last_ticks} = $ticks;
$self->{next_time} += $next_interval * $ticks;
}
elsif( $resched eq "drift" ) {
$self->{next_time} = $now + $next_interval;
}
$self->SUPER::start;
}
sub start
{
my $self = shift;
$self->{is_first} = 1;
# Only actually define a time if we've got a loop; otherwise it'll just
# become start-pending. We'll calculate it properly when it gets added to
# the Loop
if( $self->loop ) {
$self->_reschedule;
}
else {
$self->SUPER::start;
}
}
sub stop
{
my $self = shift;
$self->SUPER::stop;
undef $self->{next_time};
}
sub _make_cb
{
my $self = shift;
return $self->_capture_weakself( sub {
my $self = shift or return;
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
This method returns a hash reference of metadata that can be used to create a
YAML datastream. It is provided for authors to override or customize the fields
of F<META.yml>. E.g.
package My::Builder;
use base 'Module::Build';
sub get_metadata {
my $self, @args = @_;
my $data = $self->SUPER::get_metadata(@args);
$data->{custom_field} = 'foo';
return $data;
}
Valid arguments include:
=over
=item *
local/lib/perl5/Module/Build/Cookbook.pm view on Meta::CPAN
# Build.PL
use Module::Build;
my $class = Module::Build->subclass(
class => "Module::Build::Custom",
code => <<'SUBCLASS' );
sub ACTION_install {
my $self = shift;
# YOUR CODE HERE
$self->SUPER::ACTION_install;
}
SUBCLASS
$class->new(
module_name => 'Your::Module',
# rest of the usual Module::Build parameters
)->create_build_script;
=head2 Adding an action
local/lib/perl5/Module/Build/Platform/MacOS.pm view on Meta::CPAN
$VERSION = eval $VERSION;
use Module::Build::Base;
our @ISA = qw(Module::Build::Base);
use ExtUtils::Install;
sub have_forkpipe { 0 }
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
# $Config{sitelib} and $Config{sitearch} are, unfortunately, missing.
foreach ('sitelib', 'sitearch') {
$self->config($_ => $self->config("install$_"))
unless $self->config($_);
}
# For some reason $Config{startperl} is filled with a bunch of crap.
(my $sp = $self->config('startperl')) =~ s/.*Exit \{Status\}\s//;
$self->config(startperl => $sp);
local/lib/perl5/Module/Build/Platform/MacOS.pm view on Meta::CPAN
my $cmd = MacPerl::Pick("What build command? ('*' requires ToolServer)", @action_list);
return unless defined $cmd;
$cmd =~ s/ \*$//;
$ARGV[0] = ($cmd);
my $args = MacPerl::Ask('Any extra arguments? (ie. verbose=1)', '');
return unless defined $args;
push @ARGV, $self->split_like_shell($args);
}
$self->SUPER::dispatch(@_);
}
sub ACTION_realclean {
my $self = shift;
chmod 0666, $self->{properties}{build_script};
$self->SUPER::ACTION_realclean;
}
# ExtUtils::Install has a hard-coded '.' directory in versions less
# than 1.30. We use a sneaky trick to turn that into ':'.
#
# Note that we do it here in a cross-platform way, so this code could
# actually go in Module::Build::Base. But we put it here to be less
# intrusive for other platforms.
sub ACTION_install {
my $self = shift;
return $self->SUPER::ACTION_install(@_)
if eval {ExtUtils::Install->VERSION('1.30'); 1};
local $^W = 0; # Avoid a 'redefine' warning
local *ExtUtils::Install::find = sub {
my ($code, @dirs) = @_;
@dirs = map { $_ eq '.' ? File::Spec->curdir : $_ } @dirs;
return File::Find::find($code, @dirs);
};
return $self->SUPER::ACTION_install(@_);
}
1;
__END__
=head1 NAME
Module::Build::Platform::MacOS - Builder class for MacOS platforms
=head1 DESCRIPTION
local/lib/perl5/Module/Build/Platform/Unix.pm view on Meta::CPAN
# question "can I execute this file", but I think we want "is this
# file executable".
my ($self, $file) = @_;
return +(stat $file)[2] & 0100;
}
sub _startperl { "#! " . shift()->perl }
sub _construct {
my $self = shift()->SUPER::_construct(@_);
# perl 5.8.1-RC[1-3] had some broken %Config entries, and
# unfortunately Red Hat 9 shipped it like that. Fix 'em up here.
my $c = $self->{config};
for (qw(siteman1 siteman3 vendorman1 vendorman3)) {
$c->{"install${_}dir"} ||= $c->{"install${_}"};
}
return $self;
}
local/lib/perl5/Module/Build/Platform/VMS.pm view on Meta::CPAN
=over 4
=item _set_defaults
Change $self->{build_script} to 'Build.com' so @Build works.
=cut
sub _set_defaults {
my $self = shift;
$self->SUPER::_set_defaults(@_);
$self->{properties}{build_script} = 'Build.com';
}
=item cull_args
'@Build foo' on VMS will not preserve the case of 'foo'. Rather than forcing
people to write '@Build "foo"' we'll dispatch case-insensitively.
=cut
sub cull_args {
my $self = shift;
my($action, $args) = $self->SUPER::cull_args(@_);
my @possible_actions = grep { lc $_ eq lc $action } $self->known_actions;
die "Ambiguous action '$action'. Could be one of @possible_actions"
if @possible_actions > 1;
return ($possible_actions[0], $args);
}
=item manpage_separator
local/lib/perl5/Module/Build/Platform/VMS.pm view on Meta::CPAN
my ($self, $command) = @_;
# a lot of VMS executables have a symbol defined
# check those first
if ( $^O eq 'VMS' ) {
require VMS::DCLsym;
my $syms = VMS::DCLsym->new;
return $command if scalar $syms->getsym( uc $command );
}
$self->SUPER::find_command($command);
}
# _maybe_command copied from ExtUtils::MM_VMS::maybe_command
=item _maybe_command (override)
Follows VMS naming conventions for executable files.
If the name passed in doesn't exactly match an executable file,
appends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
to check for DCL procedure. If this fails, checks directories in DCL$PATH
local/lib/perl5/Module/Build/Platform/VMS.pm view on Meta::CPAN
}
=item oneliner
Override to ensure that we do not quote the command.
=cut
sub oneliner {
my $self = shift;
my $oneliner = $self->SUPER::oneliner(@_);
$oneliner =~ s/^\"\S+\"//;
return "MCR $^X $oneliner";
}
=item rscan_dir
Inherit the standard version but remove dots at end of name.
If the extended character set is in effect, do not remove dots from filenames
with Unix path delimiters.
=cut
sub rscan_dir {
my ($self, $dir, $pattern) = @_;
my $result = $self->SUPER::rscan_dir( $dir, $pattern );
for my $file (@$result) {
if (!_efs() && ($file =~ m#/#)) {
$file =~ s/\.$//;
}
}
return $result;
}
=item dist_dir
Inherit the standard version but replace embedded dots with underscores because
a dot is the directory delimiter on VMS.
=cut
sub dist_dir {
my $self = shift;
my $dist_dir = $self->SUPER::dist_dir;
$dist_dir =~ s/\./_/g unless _efs();
return $dist_dir;
}
=item man3page_name
Inherit the standard version but chop the extra manpage delimiter off the front if
there is one. The VMS version of splitdir('[.foo]') returns '', 'foo'.
=cut
sub man3page_name {
my $self = shift;
my $mpname = $self->SUPER::man3page_name( shift );
my $sep = $self->manpage_separator;
$mpname =~ s/^$sep//;
return $mpname;
}
=item expand_test_dir
Inherit the standard version but relativize the paths as the native glob() doesn't
do that for us.
=cut
sub expand_test_dir {
my ($self, $dir) = @_;
my @reldirs = $self->SUPER::expand_test_dir( $dir );
for my $eachdir (@reldirs) {
my ($v,$d,$f) = File::Spec->splitpath( $eachdir );
my $reldir = File::Spec->abs2rel( File::Spec->catpath( $v, $d, '' ) );
$eachdir = File::Spec->catfile( $reldir, $f );
}
return @reldirs;
}
=item _detildefy