Feature #11339 ยป 0001-io.c-avoid-kwarg-parsing-in-C-API.patch
benchmark/bm_io_nonblock_noex2.rb | ||
---|---|---|
nr = 1_000_000
|
||
i = 0
|
||
msg = '.'
|
||
buf = '.'
|
||
begin
|
||
r, w = IO.pipe
|
||
while i < nr
|
||
i += 1
|
||
w.write_nonblock(msg, exception: false)
|
||
r.read_nonblock(1, buf, exception: false)
|
||
end
|
||
rescue ArgumentError # old Rubies
|
||
while i < nr
|
||
i += 1
|
||
w.write_nonblock(msg)
|
||
r.read_nonblock(1, buf)
|
||
end
|
||
ensure
|
||
r.close
|
||
w.close
|
||
end
|
io.c | ||
---|---|---|
*/
|
||
static VALUE
|
||
io_read_nonblock(int argc, VALUE *argv, VALUE io)
|
||
{
|
||
VALUE ret, opts;
|
||
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
|
||
ret = io_getpartial(argc, argv, io, opts, 1);
|
||
if (NIL_P(ret)) {
|
||
if (no_exception_p(opts))
|
||
return Qnil;
|
||
else
|
||
rb_eof_error();
|
||
}
|
||
return ret;
|
||
}
|
||
static VALUE
|
||
io_write_nonblock(VALUE io, VALUE str, VALUE opts)
|
||
io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
|
||
{
|
||
rb_io_t *fptr;
|
||
long n;
|
||
long n, len;
|
||
struct read_internal_arg arg;
|
||
if (!RB_TYPE_P(str, T_STRING))
|
||
str = rb_obj_as_string(str);
|
||
if ((len = NUM2LONG(length)) < 0) {
|
||
rb_raise(rb_eArgError, "negative length %ld given", len);
|
||
}
|
||
io = GetWriteIO(io);
|
||
io_setstrbuf(&str,len);
|
||
OBJ_TAINT(str);
|
||
GetOpenFile(io, fptr);
|
||
rb_io_check_writable(fptr);
|
||
rb_io_check_byte_readable(fptr);
|
||
if (io_fflush(fptr) < 0)
|
||
rb_sys_fail(0);
|
||
if (len == 0)
|
||
return str;
|
||
rb_io_set_nonblock(fptr);
|
||
n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
|
||
n = read_buffered_data(RSTRING_PTR(str), len, fptr);
|
||
if (n <= 0) {
|
||
rb_io_set_nonblock(fptr);
|
||
io_setstrbuf(&str, len);
|
||
arg.fd = fptr->fd;
|
||
arg.str_ptr = RSTRING_PTR(str);
|
||
arg.len = len;
|
||
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
|
||
n = arg.len;
|
||
if (n < 0) {
|
||
if ((errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||
if (ex == Qfalse) return sym_wait_readable;
|
||
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block");
|
||
}
|
||
rb_sys_fail_path(fptr->pathv);
|
||
}
|
||
}
|
||
io_set_read_length(str, n);
|
||
if (n == -1) {
|
||
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||
if (no_exception_p(opts)) {
|
||
return sym_wait_writable;
|
||
}
|
||
else {
|
||
rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
|
||
}
|
||
}
|
||
rb_sys_fail_path(fptr->pathv);
|
||
if (n == 0) {
|
||
if (ex == Qfalse) return Qnil;
|
||
rb_eof_error();
|
||
}
|
||
return LONG2FIX(n);
|
||
return str;
|
||
}
|
||
/*
|
||
... | ... | |
* return the symbol :wait_writable instead.
|
||
*
|
||
*/
|
||
static VALUE
|
||
rb_io_write_nonblock(int argc, VALUE *argv, VALUE io)
|
||
io_write_nonblock(VALUE io, VALUE str, VALUE ex)
|
||
{
|
||
VALUE str, opts;
|
||
rb_io_t *fptr;
|
||
long n;
|
||
rb_scan_args(argc, argv, "10:", &str, &opts);
|
||
if (!RB_TYPE_P(str, T_STRING))
|
||
str = rb_obj_as_string(str);
|
||
return io_write_nonblock(io, str, opts);
|
||
io = GetWriteIO(io);
|
||
GetOpenFile(io, fptr);
|
||
rb_io_check_writable(fptr);
|
||
if (io_fflush(fptr) < 0)
|
||
rb_sys_fail(0);
|
||
rb_io_set_nonblock(fptr);
|
||
n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
|
||
if (n == -1) {
|
||
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||
if (ex == Qfalse) {
|
||
return sym_wait_writable;
|
||
}
|
||
else {
|
||
rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
|
||
}
|
||
}
|
||
rb_sys_fail_path(fptr->pathv);
|
||
}
|
||
return LONG2FIX(n);
|
||
}
|
||
/*
|
||
... | ... | |
rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1);
|
||
rb_define_method(rb_cIO, "read_nonblock", io_read_nonblock, -1);
|
||
rb_define_method(rb_cIO, "write_nonblock", rb_io_write_nonblock, -1);
|
||
rb_define_private_method(rb_cIO, "__read_nonblock", io_read_nonblock, 3);
|
||
rb_define_private_method(rb_cIO, "__write_nonblock", io_write_nonblock, 2);
|
||
rb_define_method(rb_cIO, "readpartial", io_readpartial, -1);
|
||
rb_define_method(rb_cIO, "read", io_read, -1);
|
||
rb_define_method(rb_cIO, "write", io_write_m, 1);
|
prelude.rb | ||
---|---|---|
}
|
||
end
|
||
end
|
||
class IO
|
||
def read_nonblock(len, buf = nil, exception: true)
|
||
__read_nonblock(len, buf, exception)
|
||
end
|
||
def write_nonblock(buf, exception: true)
|
||
__write_nonblock(buf, exception)
|
||
end
|
||
end
|
||
-
|