File Coverage

blib/lib/Coro/Select.pm
Criterion Covered Total %
statement 24 47 51.0
branch 1 12 8.3
condition 0 3 0.0
subroutine 8 10 80.0
pod 0 1 0.0
total 33 73 45.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Coro::Select - a (slow but coro-aware) replacement for CORE::select
4              
5             =head1 SYNOPSIS
6              
7             use Coro::Select; # replace select globally (be careful, see below)
8             use Core::Select 'select'; # only in this module
9             use Coro::Select (); # use Coro::Select::select
10              
11             =head1 DESCRIPTION
12              
13             This module tries to create a fully working replacement for perl's
14             C
15             threads can run in parallel to any select user. As many libraries that
16             only have a blocking API do not use global variables and often use select
17             (or IO::Select), this effectively makes most such libraries "somewhat"
18             non-blocking w.r.t. other threads.
19              
20             This implementation works fastest when only very few bits are set in the
21             fd set(s).
22              
23             To be effective globally, this module must be C'd before any other
24             module that uses C
25             C'd in the main program. Note that overriding C
26             might actually cause problems, as some C backends use C
27             themselves, and asking AnyEvent to use Coro::Select, which in turn asks
28             AnyEvent will not quite work.
29              
30             You can also invoke it from the commandline as C.
31              
32             To override select only for a single module (e.g. C),
33             use a code fragment like this to load it:
34              
35             {
36             package Net::DBus::Reactor;
37             use Coro::Select qw(select);
38             use Net::DBus::Reactor;
39             }
40              
41             Some modules (notably L) directly call
42             C. For these modules, we need to patch the opcode table by
43             sandwiching it between calls to C and
44             C:
45              
46             BEGIN {
47             use Coro::Select ();
48             Coro::Select::patch_pp_sselect;
49             require evil_poe_module_using_CORE::SELECT;
50             Coro::Select::unpatch_pp_sselect;
51             }
52              
53             =over 4
54              
55             =cut
56              
57             package Coro::Select;
58              
59 1     1   957 use common::sense;
  1         3  
  1         8  
60              
61 1     1   69 use Errno;
  1         3  
  1         109  
62              
63 1     1   9 use Coro ();
  1         3  
  1         23  
64 1     1   6 use Coro::State ();
  1         4  
  1         33  
65 1     1   6 use AnyEvent 4.800001 ();
  1         41  
  1         31  
66 1     1   8 use Coro::AnyEvent ();
  1         3  
  1         26  
67              
68 1     1   6 use base Exporter::;
  1         3  
  1         686  
69              
70             our $VERSION = 6.512;
71             our @EXPORT_OK = "select";
72              
73             sub import {
74 1     1   9 my $pkg = shift;
75 1 50       5 if (@_) {
76 0         0 $pkg->export (scalar caller 0, @_);
77             } else {
78 1         101 $pkg->export ("CORE::GLOBAL", "select");
79             }
80             }
81              
82             sub select(;*$$$) { # not the correct prototype, but well... :()
83 0 0 0 0 0   if (@_ == 0) {
    0          
    0          
84 0           return CORE::select
85             } elsif (@_ == 1) {
86 0           return CORE::select $_[0]
87             } elsif (defined $_[3] && !$_[3]) {
88 0           return CORE::select $_[0], $_[1], $_[2], $_[3]
89             } else {
90 0           my $nfound = 0;
91 0           my @w;
92 0           my $wakeup = Coro::rouse_cb;
93              
94             # AnyEvent does not do 'e', so replace it by 'r'
95 0           for ([0, 0], [1, 1], [2, 0]) {
96 0           my ($i, $poll) = @$_;
97 0 0         if (defined $_[$i]) {
98 0           my $rvec = \$_[$i];
99              
100             # we parse the bitmask by first expanding it into
101             # a string of bits
102 0           for (unpack "b*", $$rvec) {
103             # and then repeatedly matching a regex against it
104 0           while (/1/g) {
105 0           my $fd = (pos) - 1;
106              
107             push @w,
108             AE::io $fd, $poll, sub {
109 0     0     (vec $$rvec, $fd, 1) = 1;
110 0           ++$nfound;
111 0           $wakeup->();
112 0           };
113             }
114             }
115              
116 0           $$rvec ^= $$rvec; # clear all bits
117             }
118             }
119              
120 0 0         push @w,
121             AE::timer $_[3], 0, $wakeup
122             if defined $_[3];
123              
124 0           Coro::rouse_wait;
125              
126 0           return $nfound
127             }
128             }
129              
130             1;
131              
132             =back
133              
134             =head1 BUGS
135              
136             For performance reasons, Coro::Select's select function might not
137             properly detect bad file descriptors (but relying on EBADF is inherently
138             non-portable).
139              
140             =head1 SEE ALSO
141              
142             L.
143              
144             =head1 AUTHOR/SUPPORT/CONTACT
145              
146             Marc A. Lehmann
147             http://software.schmorp.de/pkg/Coro.html
148              
149             =cut
150              
151