Future-IO

 view release on metacpan or  search on metacpan

lib/Future/IO.pm  view on Meta::CPAN

First, if C<PERL_FUTURE_IO_IMPL> is set, any of the names given are tried, in
order.

=item 2.

Then any of the modules that attempt to wrap other event systems such as L<UV>
or L<Glib> are attempted if it is detected that the other event system is
already loaded.

=item 3.

If none of these were successful, next it attempts any OS-specific modules
based on the OS name (given by C<$^O>).

=item 4.

Finally, a list of other generic modules is attempted, which also includes
any of the wrapper implementations that can be started independently.

=back

For more details, consult the implementation code in this module to find the
current list of known modules and the order they are attempted in.

=cut

# Try to account for every Future::IO::Impl::* module on CPAN
#
# Purposely omitting:
#    Future::IO::Impl::Tickit - requires a $tickit instance to work

my @IMPLS_WRAPPER = (
   "UV",
   "Glib",
   [ IOAsync => "IO::Async::Loop" ],
   "POE",
   "AnyEvent",
);

my %IMPLS_FOR_OS = (
   darwin  => [qw( KQueue )],
   freebsd => [qw( KQueue )], # TODO and probably other BSDs
   linux   => [qw( Uring )],
   openbsd => [qw( KQueue )],
   # TODO: other OSes?
);

my @IMPLS_GENERIC = (qw(
   Ppoll
   UV
   Glib
));

sub load_best_impl
{
   shift;

   my @prefer;
   my %veto;

   foreach ( split m/,/, $ENV{PERL_FUTURE_IO_IMPL} // "" ) {
      if( s/^-// ) {
         $veto{$_} = 1;
      }
      else {
         push @prefer, $_;
      }
   }

   foreach my $impl ( @prefer ) {
      $veto{$impl} and next;
      Future::IO->try_load_impl( $impl ) and return 1;
   }

   # First, load a wrapper impl if the wrapped system is already loaded
   foreach ( @IMPLS_WRAPPER ) {
      my ( $impl, $package ) = ref $_ ? @$_ : ( $_, $_ );
      $veto{$impl} and next;
      eval { $package->VERSION(0) } or next;

      Future::IO->try_load_impl( $impl ) and return 1;
   }

   # OK, maybe we can find a good impl for this particular OS
   foreach my $impl ( @{ $IMPLS_FOR_OS{$^O} || [] } ) {
      $veto{$impl} and next;
      Future::IO->try_load_impl( $impl ) and return 1;
   }

   # Failing all of that, try the generic ones
   foreach my $impl ( @IMPLS_GENERIC ) {
      $veto{$impl} and next;
      Future::IO->try_load_impl( $impl ) and return 1;
   }

   die "Unable to find a usable Future::IO::Impl subclass\n";
}

=head2 HAVE_MULTIPLE_FILEHANDLES

   $has = Future::IO->HAVE_MULTIPLE_FILEHANDLES;

I<Since version 0.11.>

Returns true if the underlying IO implementation actually supports multiple
filehandles. The default minimal internal implementation used not to support
this, but I<since version 0.21> it now does; so this method always returns
true.

=cut

sub HAVE_MULTIPLE_FILEHANDLES
{
   return ( $IMPL //= "Future::IO::_DefaultImpl" )->HAVE_MULTIPLE_FILEHANDLES;
}

package
   Future::IO::_DefaultImpl;
use base qw( Future::IO::ImplBase );
use Carp;



( run in 1.522 second using v1.01-cache-2.11-cpan-71847e10f99 )