diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-03-19 11:40:38 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-03-19 11:40:38 +0000 |
commit | c4049f4cb6d27ffdfe9f15f4a9ddc5a48271ecf3 (patch) | |
tree | 98df695950d4ad9be608b21479593d4825e293d9 /io.c | |
parent | b7800329d3070a4fb9f9dbdbe8b411c5f628f942 (diff) |
* io.c (rb_mWaitReadable): defined.
(rb_mWaitWritable): defined.
(io_getpartial): extend IO::WaitReadable on EWOULDBLOCK and EAGAIN.
(rb_io_write_nonblock): extend IO::WaitWritable on EWOULDBLOCK and
EAGAIN.
* error.c (make_errno_exc): extracted from rb_sys_fail.
(rb_mod_sys_fail): new function.
* include/ruby/ruby.h (rb_mod_sys_fail): declared.
(rb_mWaitReadable): declared.
(rb_mWaitWritable): declared.
* ext/socket/init.c (rsock_s_recvfrom_nonblock): extend
IO::WaitReadable on EWOULDBLOCK and EAGAIN.
(rsock_s_accept_nonblock): extend IO::WaitReadable on EWOULDBLOCK,
EAGAIN, ECONNABORTED and EPROTO.
* ext/socket/socket.c (sock_connect_nonblock): extend IO::WaitWritable
on EINPROGRESS.
* ext/socket/ancdata.c (bsock_sendmsg_internal): extend
IO::WaitWritable on EWOULDBLOCK and EAGAIN.
(bsock_recvmsg_internal): extend IO::WaitReadable on EWOULDBLOCK and
EAGAIN.
* ext/openssl/ossl_ssl.c (ossl_ssl_read_internal): raise SSLError
extended by IO::WaitReadable/IO::WaitWritable on
SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE.
* ext/openssl/ossl.c (ossl_make_error): extracted from ossl_raise.
(ossl_exc_new): new function.
* ext/openssl/ossl.h (ossl_exc_new): declared.
* lib/net/protocol.rb (rbuf_fill): rescue IO::WaitReadable and
IO::WaitWritable.
[ruby-core:22539], [ruby-dev:38140]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 29 |
1 files changed, 21 insertions, 8 deletions
@@ -110,6 +110,8 @@ extern void Init_File(void); VALUE rb_cIO; VALUE rb_eEOFError; VALUE rb_eIOError; +VALUE rb_mWaitReadable; +VALUE rb_mWaitWritable; VALUE rb_stdin, rb_stdout, rb_stderr; VALUE rb_deferr; /* rescue VIM plugin */ @@ -1754,8 +1756,8 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock) if (n < 0) { if (!nonblock && rb_io_wait_readable(fptr->fd)) goto again; - if (nonblock && errno == EWOULDBLOCK) - rb_sys_fail("WANT_READ"); + if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) + rb_mod_sys_fail(rb_mWaitReadable, "read would block"); rb_sys_fail_path(fptr->pathv); } else if (n == 0) { @@ -1855,20 +1857,24 @@ io_readpartial(int argc, VALUE *argv, VALUE io) * It causes all errors the read(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc. * The caller should care such errors. * + * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, + * it is extended by IO::WaitReadable. + * So IO::WaitReadable can be used to rescue the exceptions for retrying read_nonblock. + * * read_nonblock causes EOFError on EOF. * * If the read buffer is not empty, * read_nonblock reads from the buffer like readpartial. * In this case, the read(2) system call is not called. * - * When read_nonblock raises EWOULDBLOCK, + * When read_nonblock raises an exception kind of IO::WaitReadable, * read_nonblock should not be called * until io is readable for avoiding busy loop. * This can be done as follows. * * begin * result = io.read_nonblock(maxlen) - * rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR + * rescue IO::WaitReadable, Errno::EINTR * IO.select([io]) * retry * end @@ -1904,6 +1910,10 @@ io_read_nonblock(int argc, VALUE *argv, VALUE io) * The result may also be smaller than string.length (partial write). * The caller should care such errors and partial write. * + * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, + * it is extended by IO::WaitWritable. + * So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock. + * * # Creates a pipe. * r, w = IO.pipe * @@ -1917,14 +1927,14 @@ io_read_nonblock(int argc, VALUE *argv, VALUE io) * * If the write buffer is not empty, it is flushed at first. * - * When write_nonblock raises EWOULDBLOCK, + * When write_nonblock raises an exception kind of IO::WaitWritable, * write_nonblock should not be called * until io is writable for avoiding busy loop. * This can be done as follows. * * begin * result = io.write_nonblock(string) - * rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR + * rescue IO::WaitWritable, Errno::EINTR * IO.select(nil, [io]) * retry * end @@ -1955,8 +1965,8 @@ rb_io_write_nonblock(VALUE io, VALUE str) n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str)); if (n == -1) { - if (errno == EWOULDBLOCK) - rb_sys_fail("WANT_WRITE"); + if (errno == EWOULDBLOCK || errno == EAGAIN) + rb_mod_sys_fail(rb_mWaitWritable, "write would block"); rb_sys_fail_path(fptr->pathv); } @@ -8673,6 +8683,9 @@ Init_IO(void) rb_cIO = rb_define_class("IO", rb_cObject); rb_include_module(rb_cIO, rb_mEnumerable); + rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable"); + rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable"); + #if 0 /* This is necessary only for forcing rdoc handle File::open */ rb_define_singleton_method(rb_cFile, "open", rb_io_s_open, -1); |