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