Project

General

Profile

Feature #11339 ยป 0001-io.c-avoid-kwarg-parsing-in-C-API.patch

normalperson (Eric Wong), 07/07/2015 09:59 PM

View differences:

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
-
    (1-1/1)