Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

381 lines
8.2 KiB

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