=head1 NAME Coro::Select - a (slow but coro-aware) replacement for CORE::select =head1 SYNOPSIS use Coro::Select; # replace select globally use Core::Select 'select'; # only in this module use Coro::Select (); # use Coro::Select::select =head1 DESCRIPTION This module tries to create a fully working replacement for perl's C, so it should generally be the first module C'd in the main program. You can also invoke it from the commandline as C. Performance naturally isn't great, but unless you need very high select performance you normally won't notice the difference. =over 4 =cut package Coro::Select; use strict; use Coro; use AnyEvent; use base Exporter::; our $VERSION = 4.91; our @EXPORT_OK = "select"; sub import { my $pkg = shift; if (@_) { $pkg->export (scalar caller 0, @_); } else { $pkg->export ("CORE::GLOBAL", "select"); } } sub select(;*$$$) { # not the correct prototype, but well... :() if (@_ == 0) { return CORE::select } elsif (@_ == 1) { return CORE::select $_[0] } elsif (defined $_[3] && !$_[3]) { return CORE::select $_[0], $_[1], $_[2], $_[3] } else { my $current = $Coro::current; my $nfound = 0; my @w; # AnyEvent does not do 'e', so replace it by 'r' for ([0, 'r', '<'], [1, 'w', '>'], [2, 'r', '<']) { my ($i, $poll, $mode) = @$_; if (defined (my $vec = $_[$i])) { my $rvec = \$_[$i]; for my $b (0 .. (8 * length $vec)) { if (vec $vec, $b, 1) { (vec $$rvec, $b, 1) = 0; open my $fh, "$mode&$b" or die "Coro::Select::fd2fh($b): $!"; push @w, AnyEvent->io (fh => $fh, poll => $poll, cb => sub { (vec $$rvec, $b, 1) = 1; $nfound++; $current->ready; undef $current; }); } } } } push @w, AnyEvent->timer (after => $_[3], cb => sub { $current->ready; undef $current; }) if defined $_[3]; # wait here &Coro::schedule; &Coro::schedule while $current; return $nfound } } 1; =back =head1 SEE ALSO L. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ =cut