IO::* enhancements.
[p5sagit/p5-mst-13.2.git] / ext / IO / lib / IO / Select.pm
CommitLineData
8add82fc 1# IO::Select.pm
7a4c00b4 2#
cf7fe8a2 3# Copyright (c) 1997-8 Graham Barr <gbarr@pobox.com>. All rights reserved.
4# This program is free software; you can redistribute it and/or
5# modify it under the same terms as Perl itself.
8add82fc 6
7package IO::Select;
8
8add82fc 9use strict;
10use vars qw($VERSION @ISA);
11require Exporter;
12
cf7fe8a2 13$VERSION = "1.13";
8add82fc 14
15@ISA = qw(Exporter); # This is only so we can do version checking
16
7a4c00b4 17sub VEC_BITS () {0}
18sub FD_COUNT () {1}
19sub FIRST_FD () {2}
760ac839 20
8add82fc 21sub new
22{
23 my $self = shift;
24 my $type = ref($self) || $self;
25
760ac839 26 my $vec = bless [undef,0], $type;
8add82fc 27
28 $vec->add(@_)
29 if @_;
30
31 $vec;
32}
33
34sub add
35{
7a4c00b4 36 shift->_update('add', @_);
37}
38
39
40sub remove
41{
42 shift->_update('remove', @_);
43}
44
45
46sub exists
47{
8add82fc 48 my $vec = shift;
7a4c00b4 49 $vec->[$vec->_fileno(shift) + FIRST_FD];
50}
8add82fc 51
760ac839 52
7a4c00b4 53sub _fileno
54{
55 my($self, $f) = @_;
56 $f = $f->[0] if ref($f) eq 'ARRAY';
57 ($f =~ /^\d+$/) ? $f : fileno($f);
8add82fc 58}
59
7a4c00b4 60sub _update
8add82fc 61{
62 my $vec = shift;
7a4c00b4 63 my $add = shift eq 'add';
8add82fc 64
7a4c00b4 65 my $bits = $vec->[VEC_BITS];
66 $bits = '' unless defined $bits;
67
68 my $count = 0;
69 my $f;
8add82fc 70 foreach $f (@_)
71 {
7a4c00b4 72 my $fn = $vec->_fileno($f);
73 next unless defined $fn;
74 my $i = $fn + FIRST_FD;
75 if ($add) {
76 if (defined $vec->[$i]) {
77 $vec->[$i] = $f; # if array rest might be different, so we update
78 next;
79 }
80 $vec->[FD_COUNT]++;
81 vec($bits, $fn, 1) = 1;
82 $vec->[$i] = $f;
83 } else { # remove
84 next unless defined $vec->[$i];
85 $vec->[FD_COUNT]--;
86 vec($bits, $fn, 1) = 0;
87 $vec->[$i] = undef;
88 }
89 $count++;
8add82fc 90 }
7a4c00b4 91 $vec->[VEC_BITS] = $vec->[FD_COUNT] ? $bits : undef;
92 $count;
8add82fc 93}
94
95sub can_read
96{
97 my $vec = shift;
98 my $timeout = shift;
27d4819a 99 my $r = $vec->[VEC_BITS];
8add82fc 100
27d4819a 101 defined($r) && (select($r,undef,undef,$timeout) > 0)
7a4c00b4 102 ? handles($vec, $r)
8add82fc 103 : ();
104}
105
106sub can_write
107{
108 my $vec = shift;
109 my $timeout = shift;
27d4819a 110 my $w = $vec->[VEC_BITS];
8add82fc 111
27d4819a 112 defined($w) && (select(undef,$w,undef,$timeout) > 0)
7a4c00b4 113 ? handles($vec, $w)
8add82fc 114 : ();
115}
116
cf7fe8a2 117sub has_exception
8add82fc 118{
119 my $vec = shift;
120 my $timeout = shift;
27d4819a 121 my $e = $vec->[VEC_BITS];
8add82fc 122
27d4819a 123 defined($e) && (select(undef,undef,$e,$timeout) > 0)
7a4c00b4 124 ? handles($vec, $e)
8add82fc 125 : ();
126}
127
cf7fe8a2 128sub has_error
129{
130 require Carp;
131 Carp::carp("Call to depreciated method 'has_error', use 'has_exception'")
132 if $^W;
133 goto &has_exception;
134}
135
760ac839 136sub count
137{
138 my $vec = shift;
139 $vec->[FD_COUNT];
140}
141
7a4c00b4 142sub bits
143{
144 my $vec = shift;
145 $vec->[VEC_BITS];
146}
147
148sub as_string # for debugging
149{
150 my $vec = shift;
151 my $str = ref($vec) . ": ";
152 my $bits = $vec->bits;
153 my $count = $vec->count;
154 $str .= defined($bits) ? unpack("b*", $bits) : "undef";
155 $str .= " $count";
156 my @handles = @$vec;
157 splice(@handles, 0, FIRST_FD);
158 for (@handles) {
159 $str .= " " . (defined($_) ? "$_" : "-");
160 }
161 $str;
162}
163
8add82fc 164sub _max
165{
166 my($a,$b,$c) = @_;
167 $a > $b
168 ? $a > $c
169 ? $a
170 : $c
171 : $b > $c
172 ? $b
173 : $c;
174}
175
176sub select
177{
178 shift
179 if defined $_[0] && !ref($_[0]);
180
181 my($r,$w,$e,$t) = @_;
182 my @result = ();
183
760ac839 184 my $rb = defined $r ? $r->[VEC_BITS] : undef;
7a4c00b4 185 my $wb = defined $w ? $w->[VEC_BITS] : undef;
186 my $eb = defined $e ? $e->[VEC_BITS] : undef;
8add82fc 187
188 if(select($rb,$wb,$eb,$t) > 0)
189 {
190 my @r = ();
191 my @w = ();
192 my @e = ();
760ac839 193 my $i = _max(defined $r ? scalar(@$r)-1 : 0,
194 defined $w ? scalar(@$w)-1 : 0,
195 defined $e ? scalar(@$e)-1 : 0);
8add82fc 196
760ac839 197 for( ; $i >= FIRST_FD ; $i--)
8add82fc 198 {
760ac839 199 my $j = $i - FIRST_FD;
8add82fc 200 push(@r, $r->[$i])
760ac839 201 if defined $rb && defined $r->[$i] && vec($rb, $j, 1);
8add82fc 202 push(@w, $w->[$i])
760ac839 203 if defined $wb && defined $w->[$i] && vec($wb, $j, 1);
8add82fc 204 push(@e, $e->[$i])
760ac839 205 if defined $eb && defined $e->[$i] && vec($eb, $j, 1);
8add82fc 206 }
207
208 @result = (\@r, \@w, \@e);
209 }
210 @result;
211}
212
7a4c00b4 213
214sub handles
8add82fc 215{
216 my $vec = shift;
217 my $bits = shift;
218 my @h = ();
219 my $i;
7a4c00b4 220 my $max = scalar(@$vec) - 1;
8add82fc 221
7a4c00b4 222 for ($i = FIRST_FD; $i <= $max; $i++)
8add82fc 223 {
224 next unless defined $vec->[$i];
225 push(@h, $vec->[$i])
7a4c00b4 226 if !defined($bits) || vec($bits, $i - FIRST_FD, 1);
8add82fc 227 }
228
229 @h;
230}
231
2321;
cf7fe8a2 233__END__
234
235=head1 NAME
236
237IO::Select - OO interface to the select system call
238
239=head1 SYNOPSIS
240
241 use IO::Select;
242
243 $s = IO::Select->new();
244
245 $s->add(\*STDIN);
246 $s->add($some_handle);
247
248 @ready = $s->can_read($timeout);
249
250 @ready = IO::Select->new(@handles)->read(0);
251
252=head1 DESCRIPTION
253
254The C<IO::Select> package implements an object approach to the system C<select>
255function call. It allows the user to see what IO handles, see L<IO::Handle>,
256are ready for reading, writing or have an error condition pending.
257
258=head1 CONSTRUCTOR
259
260=over 4
261
262=item new ( [ HANDLES ] )
263
264The constructor creates a new object and optionally initialises it with a set
265of handles.
266
267=back
268
269=head1 METHODS
270
271=over 4
272
273=item add ( HANDLES )
274
275Add the list of handles to the C<IO::Select> object. It is these values that
276will be returned when an event occurs. C<IO::Select> keeps these values in a
277cache which is indexed by the C<fileno> of the handle, so if more than one
278handle with the same C<fileno> is specified then only the last one is cached.
279
280Each handle can be an C<IO::Handle> object, an integer or an array
281reference where the first element is a C<IO::Handle> or an integer.
282
283=item remove ( HANDLES )
284
285Remove all the given handles from the object. This method also works
286by the C<fileno> of the handles. So the exact handles that were added
287need not be passed, just handles that have an equivalent C<fileno>
288
289=item exists ( HANDLE )
290
291Returns a true value (actually the handle itself) if it is present.
292Returns undef otherwise.
293
294=item handles
295
296Return an array of all registered handles.
297
298=item can_read ( [ TIMEOUT ] )
299
300Return an array of handles that are ready for reading. C<TIMEOUT> is
301the maximum amount of time to wait before returning an empty list. If
302C<TIMEOUT> is not given and any handles are registered then the call
303will block.
304
305=item can_write ( [ TIMEOUT ] )
306
307Same as C<can_read> except check for handles that can be written to.
308
309=item has_exception ( [ TIMEOUT ] )
310
311Same as C<can_read> except check for handles that have an exception
312condition, for example pending out-of-band data.
313
314=item count ()
315
316Returns the number of handles that the object will check for when
317one of the C<can_> methods is called or the object is passed to
318the C<select> static method.
319
320=item bits()
321
322Return the bit string suitable as argument to the core select() call.
323
324=item select ( READ, WRITE, ERROR [, TIMEOUT ] )
325
326C<select> is a static method, that is you call it with the package
327name like C<new>. C<READ>, C<WRITE> and C<ERROR> are either C<undef>
328or C<IO::Select> objects. C<TIMEOUT> is optional and has the same
329effect as for the core select call.
330
331The result will be an array of 3 elements, each a reference to an array
332which will hold the handles that are ready for reading, writing and have
333error conditions respectively. Upon error an empty array is returned.
334
335=back
336
337=head1 EXAMPLE
338
339Here is a short example which shows how C<IO::Select> could be used
340to write a server which communicates with several sockets while also
341listening for more connections on a listen socket
342
343 use IO::Select;
344 use IO::Socket;
345
346 $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
347 $sel = new IO::Select( $lsn );
348
349 while(@ready = $sel->can_read) {
350 foreach $fh (@ready) {
351 if($fh == $lsn) {
352 # Create a new socket
353 $new = $lsn->accept;
354 $sel->add($new);
355 }
356 else {
357 # Process socket
358
359 # Maybe we have finished with the socket
360 $sel->remove($fh);
361 $fh->close;
362 }
363 }
364 }
365
366=head1 AUTHOR
367
854822f1 368Graham Barr. Currently maintained by the Perl Porters. Please report all
369bugs to <perl5-porters@perl.org>.
cf7fe8a2 370
371=head1 COPYRIGHT
372
373Copyright (c) 1997-8 Graham Barr <gbarr@pobox.com>. All rights reserved.
374This program is free software; you can redistribute it and/or
375modify it under the same terms as Perl itself.
376
377=cut
378