Acme-Sort-Sleep

 view release on metacpan or  search on metacpan

local/lib/perl5/IO/Async/Loop.pm  view on Meta::CPAN

   foreach my $class ( @candidates ) {
      $class =~ m/::/ or $class = "IO::Async::Loop::$class";
      $self = __try_new( $class ) and return $self;

      my ( $topline ) = split m/\n/, $@; # Ignore all the other lines; they'll be require's verbose output
      warn "Unable to use $class - $topline\n";
   }

   unless( $LOOP_NO_OS ) {
      foreach my $class ( IO::Async::OS->LOOP_PREFER_CLASSES, "IO::Async::Loop::$^O" ) {
         $class =~ m/::/ or $class = "IO::Async::Loop::$class";
         $self = __try_new( $class ) and return $self;

         # Don't complain about these ones
      }
   }

   return IO::Async::Loop->new_builtin;
}

sub new_builtin
{
   shift;
   my $self;

   foreach my $class ( IO::Async::OS->LOOP_BUILTIN_CLASSES ) {
      $self = __try_new( "IO::Async::Loop::$class" ) and return $self;
   }

   croak "Cannot find a suitable candidate class";
}

#######################
# Notifier management #
#######################

=head1 NOTIFIER MANAGEMENT

The following methods manage the collection of L<IO::Async::Notifier> objects.

=cut

=head2 add

   $loop->add( $notifier )

This method adds another notifier object to the stored collection. The object
may be a L<IO::Async::Notifier>, or any subclass of it.

When a notifier is added, any children it has are also added, recursively. In
this way, entire sections of a program may be written within a tree of
notifier objects, and added or removed on one piece.

=cut

sub add
{
   my $self = shift;
   my ( $notifier ) = @_;

   if( defined $notifier->parent ) {
      croak "Cannot add a child notifier directly - add its parent";
   }

   if( defined $notifier->loop ) {
      croak "Cannot add a notifier that is already a member of a loop";
   }

   $self->_add_noparentcheck( $notifier );
}

sub _add_noparentcheck
{
   my $self = shift;
   my ( $notifier ) = @_;

   my $nkey = refaddr $notifier;

   $self->{notifiers}->{$nkey} = $notifier;

   $notifier->__set_loop( $self );

   $self->_add_noparentcheck( $_ ) for $notifier->children;

   return;
}

=head2 remove

   $loop->remove( $notifier )

This method removes a notifier object from the stored collection, and
recursively and children notifiers it contains.

=cut

sub remove
{
   my $self = shift;
   my ( $notifier ) = @_;

   if( defined $notifier->parent ) {
      croak "Cannot remove a child notifier directly - remove its parent";
   }

   $self->_remove_noparentcheck( $notifier );
}

sub _remove_noparentcheck
{
   my $self = shift;
   my ( $notifier ) = @_;

   my $nkey = refaddr $notifier;

   exists $self->{notifiers}->{$nkey} or croak "Notifier does not exist in collection";

   delete $self->{notifiers}->{$nkey};

   $notifier->__set_loop( undef );

   $self->_remove_noparentcheck( $_ ) for $notifier->children;

   return;
}

=head2 notifiers

   @notifiers = $loop->notifiers

Returns a list of all the notifier objects currently stored in the Loop.

=cut

sub notifiers
{
   my $self = shift;
   # Sort so the order remains stable under additions/removals
   return map { $self->{notifiers}->{$_} } sort keys %{ $self->{notifiers} };
}

###################
# Looping support #
###################

=head1 LOOPING CONTROL

The following methods control the actual run cycle of the loop, and hence the
program.

=cut

=head2 loop_once

   $count = $loop->loop_once( $timeout )

This method performs a single wait loop using the specific subclass's
underlying mechanism. If C<$timeout> is undef, then no timeout is applied, and
it will wait until an event occurs. The intention of the return value is to
indicate the number of callbacks that this loop executed, though different
subclasses vary in how accurately they can report this. See the documentation
for this method in the specific subclass for more information.

=cut

sub loop_once
{
   my $self = shift;
   my ( $timeout ) = @_;

   croak "Expected that $self overrides ->loop_once";
}

=head2 run

   @result = $loop->run

   $result = $loop->run

Runs the actual IO event loop. This method blocks until the C<stop> method is
called, and returns the result that was passed to C<stop>. In scalar context
only the first result is returned; the others will be discarded if more than

local/lib/perl5/IO/Async/Loop.pm  view on Meta::CPAN


   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.

The code reference is never invoked immediately, though the loop will not
perform any blocking operations between when it is installed and when it is
invoked. It may call C<select>, C<poll> or equivalent with a zero-second
timeout, and process any currently-pending IO conditions before the code is
invoked, but it will not block for a non-zero amount of time.

This method is implemented using the C<watch_idle> method, with the C<when>
parameter set to C<later>. It will return an ID value that can be passed to
C<unwatch_idle> if required.

=cut

sub later
{
   my $self = shift;
   my ( $code ) = @_;

   return $self->watch_idle( when => 'later', code => $code );
}

=head2 spawn_child

   $loop->spawn_child( %params )

This method creates a new child process to run a given code block or command.
For more detail, see the C<spawn_child> method on the
L<IO::Async::ChildManager> class.

=cut

sub spawn_child
{
   my $self = shift;
   my %params = @_;

   my $childmanager = $self->{childmanager} ||=
      $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

=item code => CODE

The command or code to run in the child process (as per the C<spawn> method)

=item on_finish => CODE

A continuation to be called when the child process exits and has closed all of
the filehandles that were set up for it. It will be invoked in the following
way:

 $on_finish->( $pid, $exitcode )

The second argument is passed the plain perl C<$?> value.

=item on_error => CODE

Optional continuation to be called when the child code block throws an
exception, or the command could not be C<exec(2)>ed. It will be invoked in the
following way (as per C<spawn>)

 $on_error->( $pid, $exitcode, $dollarbang, $dollarat )

If this continuation is not supplied, then C<on_finish> is used instead. The
value of C<$!> and C<$@> will not be reported.

=item setup => ARRAY

Optional reference to an array to pass to the underlying C<spawn> method.

=back

In addition, the hash takes keys that define how to set up file descriptors in
the child process. (If the C<setup> array is also given, these operations will
be performed after those specified by C<setup>.)

=over 8

=item fdI<n> => HASH

A hash describing how to set up file descriptor I<n>. The hash may contain one
of the following sets of keys:

=over 4

=item on_read => CODE

The child will be given the writing end of a pipe. The reading end will be
wrapped by an L<IO::Async::Stream> using this C<on_read> callback function.

=item from => STRING



( run in 0.761 second using v1.01-cache-2.11-cpan-39bf76dae61 )