=head1 NAME Coro::Select - a (slow but coro-aware) replacement for CORE::select =head1 SYNOPSIS use Coro::Select; # replace select globally (be careful, see below) 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. Note that overriding C themselves, and asking AnyEvent to use Coro::Select, which in turn asks AnyEvent will not quite work. You can also invoke it from the commandline as C. To override select only for a single module (e.g. C), use a code fragment like this to load it: { package Net::DBus::Reactor; use Coro::Select qw(select); use Net::DBus::Reactor; } Some modules (notably L) directly call C. For these modules, we need to patch the opcode table by sandwiching it between calls to C and C: BEGIN { use Coro::Select (); Coro::Select::patch_pp_sselect; require evil_poe_module_using_CORE::SELECT; Coro::Select::unpatch_pp_sselect; } =over 4 =cut package Coro::Select; use common::sense; use Errno; use Coro (); use Coro::State (); use AnyEvent 4.800001 (); use Coro::AnyEvent (); use base Exporter::; our $VERSION = 6.04; 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 $nfound = 0; my @w; my $wakeup = Coro::rouse_cb; # AnyEvent does not do 'e', so replace it by 'r' for ([0, 0], [1, 1], [2, 0]) { my ($i, $poll) = @$_; if (defined $_[$i]) { my $rvec = \$_[$i]; # we parse the bitmask by first expanding it into # a string of bits for (unpack "b*", $$rvec) { # and then repeatedly matching a regex against it while (/1/g) { my $fd = (pos) - 1; push @w, AE::io $fd, $poll, sub { (vec $$rvec, $fd, 1) = 1; ++$nfound; $wakeup->(); }; } } $$rvec ^= $$rvec; # clear all bits } } push @w, AE::timer $_[3], 0, $wakeup if defined $_[3]; Coro::rouse_wait; return $nfound } } 1; =back =head1 BUGS For performance reasons, Coro::Select's select function might not properly detect bad file descriptors (but relying on EBADF is inherently non-portable). =head1 SEE ALSO L. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ =cut