Feature #11056 » io_wait_readable-no-nread-experimental.patch
| ext/io/wait/wait.c | ||
|---|---|---|
|
#define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue)
|
||
|
#endif
|
||
|
static VALUE sym_wait_only;
|
||
|
static VALUE io_ready_p _((VALUE io));
|
||
|
static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io));
|
||
|
static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io));
|
||
| ... | ... | |
|
io_wait_readable(int argc, VALUE *argv, VALUE io)
|
||
|
{
|
||
|
rb_io_t *fptr;
|
||
|
VALUE opts = Qnil;
|
||
|
int i;
|
||
|
ioctl_arg n;
|
||
|
VALUE timeout;
|
||
|
struct timeval timerec;
|
||
|
struct timeval *tv;
|
||
|
int check_nread = 1;
|
||
|
GetOpenFile(io, fptr);
|
||
|
rb_io_check_readable(fptr);
|
||
|
rb_scan_args(argc, argv, "01", &timeout);
|
||
|
rb_scan_args(argc, argv, "01:", &timeout, &opts);
|
||
|
if (!NIL_P(opts) && Qtrue == rb_hash_lookup2(opts, sym_wait_only, Qundef))
|
||
|
check_nread = 0;
|
||
|
if (NIL_P(timeout)) {
|
||
|
tv = NULL;
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
if (rb_io_read_pending(fptr)) return Qtrue;
|
||
|
if (!FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
|
||
|
if (check_nread && !FIONREAD_POSSIBLE_P(fptr->fd)) return Qfalse;
|
||
|
i = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, tv);
|
||
|
if (i < 0)
|
||
|
rb_sys_fail(0);
|
||
|
rb_io_check_closed(fptr);
|
||
|
if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
|
||
|
if (n > 0) return io;
|
||
|
if (check_nread) {
|
||
|
ioctl_arg n;
|
||
|
if (ioctl(fptr->fd, FIONREAD, &n)) rb_sys_fail(0);
|
||
|
if (n > 0) return io;
|
||
|
} else {
|
||
|
if (i & RB_WAITFD_IN)
|
||
|
return io;
|
||
|
}
|
||
|
return Qnil;
|
||
|
}
|
||
| ... | ... | |
|
rb_define_method(rb_cIO, "wait", io_wait_readable, -1);
|
||
|
rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
|
||
|
rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1);
|
||
|
sym_wait_only = ID2SYM(rb_intern("wait_only"));
|
||
|
}
|
||
| lib/net/http/generic_request.rb | ||
|---|---|---|
|
def wait_for_continue(sock, ver)
|
||
|
if ver >= '1.1' and @header['expect'] and
|
||
|
@header['expect'].include?('100-continue')
|
||
|
if IO.select([sock.io], nil, nil, sock.continue_timeout)
|
||
|
if sock.io.to_io.wait_readable(sock.continue_timeout, wait_only: true)
|
||
|
res = Net::HTTPResponse.read_new(sock)
|
||
|
unless res.kind_of?(Net::HTTPContinue)
|
||
|
res.decode_content = @decode_content
|
||
| lib/net/protocol.rb | ||
|---|---|---|
|
require 'socket'
|
||
|
require 'timeout'
|
||
|
require 'io/wait'
|
||
|
module Net # :nodoc:
|
||
| ... | ... | |
|
when String
|
||
|
return @rbuf << rv
|
||
|
when :wait_readable
|
||
|
IO.select([@io], nil, nil, @read_timeout) or raise Net::ReadTimeout
|
||
|
@io.to_io.wait_readable(@read_timeout, wait_only: true) or
|
||
|
raise Net::ReadTimeout
|
||
|
# continue looping
|
||
|
when :wait_writable
|
||
|
# OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
|
||
|
# http://www.openssl.org/support/faq.html#PROG10
|
||
|
IO.select(nil, [@io], nil, @read_timeout) or raise Net::ReadTimeout
|
||
|
@io.to_io.wait_writable(@read_timeout) or raise Net::ReadTimeout
|
||
|
# continue looping
|
||
|
when nil
|
||
|
# callers do not care about backtrace, so avoid allocating for it
|
||
| test/io/wait/test_io_wait.rb | ||
|---|---|---|
|
assert_raises(IOError) { @w.wait_writable }
|
||
|
end
|
||
|
def test_wait_readable_wait_only
|
||
|
host = '127.0.0.1'
|
||
|
s = TCPServer.new(host, 0)
|
||
|
assert_nil s.wait_readable(0.01, wait_only: true)
|
||
|
c = TCPSocket.new(host, s.addr[1])
|
||
|
assert_equal s, s.wait_readable(wait_only: true)
|
||
|
ensure
|
||
|
s.close if s
|
||
|
c.close if c
|
||
|
end
|
||
|
private
|
||
|
def fill_pipe
|
||
|
-
|
||
- « Previous
- 1
- 2
- Next »