ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Select.pm
Revision: 1.99
Committed: Mon Mar 16 11:12:52 2020 UTC (4 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-6_57, HEAD
Changes since 1.98: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
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<select> built-in, using C<AnyEvent> watchers to do the job, so other
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<use>'d before any other
24 module that uses C<select>, so it should generally be the first module
25 C<use>'d in the main program. Note that overriding C<select> globally
26 might actually cause problems, as some C<AnyEvent> backends use C<select>
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<perl -MCoro::Select>.
31
32 To override select only for a single module (e.g. C<Net::DBus::Reactor>),
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<POE::Loop::Select>) directly call
42 C<CORE::select>. For these modules, we need to patch the opcode table by
43 sandwiching it between calls to C<Coro::Select::patch_pp_sselect> and
44 C<Coro::Select::unpatch_pp_sselect>:
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 use common::sense;
60
61 use Errno;
62
63 use Coro ();
64 use Coro::State ();
65 use AnyEvent 4.800001 ();
66 use Coro::AnyEvent ();
67
68 use base Exporter::;
69
70 our $VERSION = 6.57;
71 our @EXPORT_OK = "select";
72
73 sub import {
74 my $pkg = shift;
75 if (@_) {
76 $pkg->export (scalar caller 0, @_);
77 } else {
78 $pkg->export ("CORE::GLOBAL", "select");
79 }
80 }
81
82 sub select(;*$$$) {
83 if (@_ == 0) {
84 return CORE::select
85 } elsif (@_ == 1) {
86 return CORE::select $_[0]
87 } elsif (defined $_[3] && !$_[3]) {
88 return CORE::select $_[0], $_[1], $_[2], $_[3]
89 } else {
90 my $nfound = 0;
91 my @w;
92 my $wakeup = Coro::rouse_cb;
93
94 # AnyEvent does not do 'e', so replace it by 'r'
95 for ([0, 0], [1, 1], [2, 0]) {
96 my ($i, $poll) = @$_;
97 if (defined $_[$i]) {
98 my $rvec = \$_[$i];
99
100 # we parse the bitmask by first expanding it into
101 # a string of bits
102 for (unpack "b*", $$rvec) {
103 # and then repeatedly matching a regex against it
104 while (/1/g) {
105 my $fd = (pos) - 1;
106
107 push @w,
108 AE::io $fd, $poll, sub {
109 (vec $$rvec, $fd, 1) = 1;
110 ++$nfound;
111 $wakeup->();
112 };
113 }
114 }
115
116 $$rvec ^= $$rvec; # clear all bits
117 }
118 }
119
120 push @w,
121 AE::timer $_[3], 0, $wakeup
122 if defined $_[3];
123
124 Coro::rouse_wait;
125
126 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<Coro::LWP>.
143
144 =head1 AUTHOR/SUPPORT/CONTACT
145
146 Marc A. Lehmann <schmorp@schmorp.de>
147 http://software.schmorp.de/pkg/Coro.html
148
149 =cut
150
151