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