diff options
Diffstat (limited to 'ext/IO/lib/IO/Select.pm')
-rw-r--r-- | ext/IO/lib/IO/Select.pm | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/ext/IO/lib/IO/Select.pm b/ext/IO/lib/IO/Select.pm index 208be0cf53..ed8c2bb983 100644 --- a/ext/IO/lib/IO/Select.pm +++ b/ext/IO/lib/IO/Select.pm @@ -49,7 +49,9 @@ handle with the same C<fileno> is specified then only the last one is cached. =item remove ( HANDLES ) -Remove all the given handles from the object. +Remove all the given handles from the object. This method also works +by the C<fileno> of the handles. So the exact handles that were added +need not be passed, just handles that have an equivalent C<fileno> =item can_read ( [ TIMEOUT ] ) @@ -66,6 +68,12 @@ Same as C<can_read> except check for handles that can be written to. Same as C<can_read> except check for handles that have an error condition, for example EOF. +=item count () + +Returns the number of handles that the object will check for when +one of the C<can_> methods is called or the object is passed to +the C<select> static method. + =item select ( READ, WRITE, ERROR [, TIMEOUT ] ) C<select> is a static method, that is you call it with the package name @@ -132,12 +140,16 @@ $VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/); @ISA = qw(Exporter); # This is only so we can do version checking +sub VEC_BITS {0} +sub FD_COUNT {1} +sub FIRST_FD {2} + sub new { my $self = shift; my $type = ref($self) || $self; - my $vec = bless [''], $type; + my $vec = bless [undef,0], $type; $vec->add(@_) if @_; @@ -150,14 +162,19 @@ sub add my $vec = shift; my $f; + $vec->[VEC_BITS] = '' unless defined $vec->[VEC_BITS]; + foreach $f (@_) { my $fn = $f =~ /^\d+$/ ? $f : fileno($f); next unless defined $fn; - vec($vec->[0],$fn++,1) = 1; - $vec->[$fn] = $f; + vec($vec->[VEC_BITS],$fn,1) = 1; + $vec->[FD_COUNT] += 1 + unless defined $vec->[$fn+FIRST_FD]; + $vec->[$fn+FIRST_FD] = $f; } + $vec->[VEC_BITS] = undef unless $vec->count; } sub remove @@ -170,9 +187,11 @@ sub remove my $fn = $f =~ /^\d+$/ ? $f : fileno($f); next unless defined $fn; - vec($vec->[0],$fn++,1) = 0; - $vec->[$fn] = undef; + vec($vec->[VEC_BITS],$fn,1) = 0; + $vec->[$fn+FIRST_FD] = undef; + $vec->[FD_COUNT] -= 1; } + $vec->[VEC_BITS] = undef unless $vec->count; } sub can_read @@ -180,7 +199,7 @@ sub can_read my $vec = shift; my $timeout = shift; - my $r = $vec->[0]; + my $r = $vec->[VEC_BITS] or return (); select($r,undef,undef,$timeout) > 0 ? _handles($vec, $r) @@ -192,7 +211,7 @@ sub can_write my $vec = shift; my $timeout = shift; - my $w = $vec->[0]; + my $w = $vec->[VEC_BITS] or return (); select(undef,$w,undef,$timeout) > 0 ? _handles($vec, $w) @@ -204,13 +223,19 @@ sub has_error my $vec = shift; my $timeout = shift; - my $e = $vec->[0]; + my $e = $vec->[VEC_BITS] or return (); select(undef,undef,$e,$timeout) > 0 ? _handles($vec, $e) : (); } +sub count +{ + my $vec = shift; + $vec->[FD_COUNT]; +} + sub _max { my($a,$b,$c) = @_; @@ -231,28 +256,28 @@ sub select my($r,$w,$e,$t) = @_; my @result = (); - my $rb = defined $r ? $r->[0] : undef; - my $wb = defined $w ? $e->[0] : undef; - my $eb = defined $e ? $w->[0] : undef; + my $rb = defined $r ? $r->[VEC_BITS] : undef; + my $wb = defined $w ? $e->[VEC_BITS] : undef; + my $eb = defined $e ? $w->[VEC_BITS] : undef; if(select($rb,$wb,$eb,$t) > 0) { my @r = (); my @w = (); my @e = (); - my $i = _max(defined $r ? scalar(@$r) : 0, - defined $w ? scalar(@$w) : 0, - defined $e ? scalar(@$e) : 0); + my $i = _max(defined $r ? scalar(@$r)-1 : 0, + defined $w ? scalar(@$w)-1 : 0, + defined $e ? scalar(@$e)-1 : 0); - for( ; $i > 0 ; $i--) + for( ; $i >= FIRST_FD ; $i--) { - my $j = $i - 1; + my $j = $i - FIRST_FD; push(@r, $r->[$i]) - if defined $r->[$i] && vec($rb, $j, 1); + if defined $rb && defined $r->[$i] && vec($rb, $j, 1); push(@w, $w->[$i]) - if defined $w->[$i] && vec($wb, $j, 1); + if defined $wb && defined $w->[$i] && vec($wb, $j, 1); push(@e, $e->[$i]) - if defined $e->[$i] && vec($eb, $j, 1); + if defined $eb && defined $e->[$i] && vec($eb, $j, 1); } @result = (\@r, \@w, \@e); @@ -267,14 +292,15 @@ sub _handles my @h = (); my $i; - for($i = scalar(@$vec) - 1 ; $i > 0 ; $i--) + for($i = scalar(@$vec) - 1 ; $i >= FIRST_FD ; $i--) { next unless defined $vec->[$i]; push(@h, $vec->[$i]) - if vec($bits,$i - 1,1); + if vec($bits,$i - FIRST_FD,1); } @h; } 1; + |