ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Coro/Event/Select.pm
Revision: 1.4
Committed: Tue Nov 29 10:45:32 2005 UTC (20 years, 10 months ago) by root
Branch: MAIN
Changes since 1.3: +6 -5 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     Coro::Select - a (slow but event-aware) replacement for CORE::select
4    
5     =head1 SYNOPSIS
6    
7     use Coro::Select; # replace select globally
8     use Core::Select 'select'; # only in this module
9    
10     =head1 DESCRIPTION
11    
12     This module tries to create a fully working replacement for perl's
13     C<select> built-in, using C<Event> watchers to do the job, so other
14     coroutines can run in parallel.
15    
16     To be effective globally, this module must be C<use>'d before any other
17     module that uses C<select>, so it should generally be the first module
18     C<use>'d in the main program.
19    
20     You can also invoke it from the commandline as C<perl -MCoro::Select>.
21    
22     =over 4
23    
24     =cut
25    
26     package Coro::Select;
27    
28     use base Exporter;
29    
30     use Coro;
31 root 1.4 use Coro::Event;
32 root 1.1 use Event;
33    
34 root 1.3 $VERSION = 1.31;
35 root 1.1
36     BEGIN {
37     @EXPORT_OK = qw(select);
38     }
39    
40     sub import {
41     my $pkg = shift;
42     if (@_) {
43 root 1.4 $pkg->export (caller (0), @_);
44 root 1.1 } else {
45 root 1.4 $pkg->export ("CORE::GLOBAL", "select");
46 root 1.1 }
47     }
48    
49     sub select(;*$$$) { # not the correct prototype, but well... :()
50     if (@_ == 0) {
51     return CORE::select;
52     } elsif (@_ == 1) {
53     return CORE::select $_[0];
54     } elsif (defined $_[3] && !$_[3]) {
55 root 1.4 return CORE::select (@_);
56 root 1.1 } else {
57     my $current = $Coro::current;
58     my $nfound = 0;
59     my @w;
60     for ([0, 'r'], [1, 'w'], [2, 'e']) {
61     my ($i, $poll) = @$_;
62     if (defined (my $vec = $_[$i])) {
63     my $rvec = \$_[$i];
64     for my $b (0 .. (8 * length $vec)) {
65     if (vec $vec, $b, 1) {
66     (vec $$rvec, $b, 1) = 0;
67     push @w,
68 root 1.4 Event->io (fd => $b, poll => $poll, cb => sub {
69 root 1.1 (vec $$rvec, $b, 1) = 1;
70     $nfound++;
71     $current->ready;
72     });
73     }
74     }
75     }
76     }
77    
78     push @w,
79 root 1.4 Event->timer (after => $_[3], cb => sub {
80 root 1.1 $current->ready;
81     });
82    
83     Coro::schedule;
84     # wait here
85    
86     $_->cancel for @w;
87     return $nfound;
88     }
89     }
90    
91     1;
92    
93     =back
94    
95     =head1 AUTHOR
96    
97     Marc Lehmann <schmorp@schmorp.de>
98     http://home.schmorp.de/
99    
100     =cut
101    
102