U:RDoc::AnyMethod[iI"select:ETI"IO::select;TT:publico:RDoc::Markup::Document:@parts[-o:RDoc::Markup::Paragraph; [I""Calls select(2) system call. ;TI"RIt monitors given arrays of IO
objects, waits until one or more ;TI"Nof IO
objects are ready for reading, are ready for writing, ;TI"Iand have pending exceptions respectively, and returns an array that ;TI"@contains arrays of those IO objects. It will return +nil+ ;TI"Mif optional timeout value is given and no IO
object ;TI"(is ready in timeout seconds.;To:RDoc::Markup::BlankLine o;
; [
I"aIO.select
peeks the buffer of IO
objects for testing readability. ;TI"1If the IO
buffer is not empty, ;TI">IO.select
immediately notifies readability. ;TI";This "peek" only happens for IO
objects. ;TI"LIt does not happen for IO-like objects such as OpenSSL::SSL::SSLSocket.;T@o;
; [I"?The best way to use IO.select
is invoking it ;TI"eafter nonblocking methods such as read_nonblock
, write_nonblock
, etc. ;TI"9The methods raise an exception which is extended by ;TI"EIO::WaitReadable
or IO::WaitWritable
. ;TI"PThe modules notify how the caller should wait with IO.select
. ;TI"UIf IO::WaitReadable
is raised, the caller should wait for reading. ;TI"TIf IO::WaitWritable
is raised, the caller should wait for writing.;T@o;
; [I"HSo, blocking read (readpartial
) can be emulated using ;TI"Fread_nonblock
and IO.select
as follows:;T@o:RDoc::Markup::Verbatim; [I"begin
;TI". result = io_like.read_nonblock(maxlen)
;TI"rescue IO::WaitReadable
;TI" IO.select([io_like])
;TI"
retry
;TI"rescue IO::WaitWritable
;TI"! IO.select(nil, [io_like])
;TI"
retry
;TI" end
;T:@format0o;
; [
I"IO.select is preferred for IO
like ;TI";objects such as OpenSSL::SSL::SSLSocket
. ;TI"SIt has to_io
method to return underlying IO
object. ;TI"[IO.select
calls to_io
to obtain the file descriptor to wait.;T@o;
; [I"QThis means that readability notified by IO.select
doesn't mean ;TI"Breadability from OpenSSL::SSL::SSLSocket
object.;T@o;
; [I"_The most likely situation is that OpenSSL::SSL::SSLSocket
buffers some data. ;TI"4IO.select
doesn't see the buffer. ;TI"mSo IO.select
can block when OpenSSL::SSL::SSLSocket#readpartial
doesn't block.;T@o;
; [I"8However, several more complicated situations exist.;T@o;
; [I"5SSL is a protocol which is sequence of records. ;TI",The record consists of multiple bytes. ;TI"8So, the remote side of SSL sends a partial record, ;TI"5IO.select
notifies readability but ;TI"DOpenSSL::SSL::SSLSocket
cannot decrypt a byte and ;TI"BOpenSSL::SSL::SSLSocket#readpartial
will blocks.;T@o;
; [I"FAlso, the remote side can request SSL renegotiation which forces ;TI".the local SSL engine to write some data. ;TI"EThis means OpenSSL::SSL::SSLSocket#readpartial
may ;TI"=invoke write
system call and it can block. ;TI"MIn such a situation, OpenSSL::SSL::SSLSocket#read_nonblock
;TI"2raises IO::WaitWritable instead of blocking. ;TI"KSo, the caller should wait for ready for writability as above example.;T@o;
; [I"JThe combination of nonblocking methods and IO.select
is ;TI"Balso useful for streams such as tty, pipe socket socket when ;TI"+multiple processes read from a stream.;T@o;
; [ I";Finally, Linux kernel developers don't guarantee that ;TI"Jreadability of select(2) means readability of following read(2) even ;TI"for a single process. ;TI".See select(2) manual on GNU/Linux system.;T@o;
; [I"]Invoking IO.select
before IO#readpartial
works well as usual. ;TI"BHowever it is not the best way to use IO.select
.;T@o;
; [
I"8The writability notified by select(2) doesn't show ;TI"how many bytes writable. ;TI"NIO#write
method blocks until given whole string is written. ;TI"uSo, IO#write(two or more bytes)
can block after writability is notified by IO.select
. ;TI"FIO#write_nonblock
is required to avoid the blocking.;T@o;
; [I"?Blocking write (write
) can be emulated using ;TI"Hwrite_nonblock
and IO.select
as follows: ;TI"kIO::WaitReadable should also be rescued for SSL renegotiation in OpenSSL::SSL::SSLSocket
.;T@o;; [I"while 0 < string.bytesize
;TI"
begin
;TI"2 written = io_like.write_nonblock(string)
;TI" rescue IO::WaitReadable
;TI" IO.select([io_like])
;TI" retry
;TI" rescue IO::WaitWritable
;TI"# IO.select(nil, [io_like])
;TI" retry
;TI" end
;TI". string = string.byteslice(written..-1)
;TI" end
;T;
0S:RDoc::Markup::Heading:
leveli: textI"Parameters;To:RDoc::Markup::List:
@type: NOTE:@items[ o:RDoc::Markup::ListItem:@label[I"read_array;T; [o;
; [I"Gan array of IO
objects that wait until ready for read;To;;[I"write_array;T; [o;
; [I"Han array of IO
objects that wait until ready for write;To;;[I"error_array;T; [o;
; [I"Aan array of IO
objects that wait for exceptions;To;;[I"timeout;T; [o;
; [I"a numeric value in second;T@S;;i;I"Example;T@o;; [I"rp, wp = IO.pipe
;TI"mesg = "ping "
;TI"100.times {
;TI"H # IO.select follows IO#read. Not the best way to use IO.select.
;TI"' rs, ws, = IO.select([rp], [wp])
;TI" if r = rs[0]
;TI" ret = r.read(5)
;TI" print ret
;TI" case ret
;TI" when /ping/
;TI" mesg = "pong\n"
;TI" when /pong/
;TI" mesg = "ping "
;TI"
end
;TI" end
;TI" if w = ws[0]
;TI" w.write(mesg)
;TI" end
;TI"}
;T;
0o;
; [I"produces:;T@o;; [
I"ping pong
;TI"ping pong
;TI"ping pong
;TI"(snipped)
;TI" ping;T;
0:
@fileI" io.c;T:0@omit_headings_from_table_of_contents_below0I"WIO.select(read_array [, write_array [, error_array [, timeout]]]) -> array or nil
;T0[ I"$(p1, p2 = v2, p3 = v3, p4 = v4);T@½FI"IO;TcRDoc::NormalClass00