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