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
1
nr = 1_000_000
2
i = 0
3
msg = '.'
4
buf = '.'
5
begin
6
  r, w = IO.pipe
7
  while i < nr
8
    i += 1
9
    w.write_nonblock(msg, exception: false)
10
    r.read_nonblock(1, buf, exception: false)
11
  end
12
rescue ArgumentError # old Rubies
13
  while i < nr
14
    i += 1
15
    w.write_nonblock(msg)
16
    r.read_nonblock(1, buf)
17
  end
18
ensure
19
  r.close
20
  w.close
21
end
io.c
2671 2671
 */
2672 2672

  
2673 2673
static VALUE
2674
io_read_nonblock(int argc, VALUE *argv, VALUE io)
2675
{
2676
    VALUE ret, opts;
2677

  
2678
    rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
2679

  
2680
    ret = io_getpartial(argc, argv, io, opts, 1);
2681

  
2682
    if (NIL_P(ret)) {
2683
	if (no_exception_p(opts))
2684
	    return Qnil;
2685
	else
2686
	    rb_eof_error();
2687
    }
2688
    return ret;
2689
}
2690

  
2691
static VALUE
2692
io_write_nonblock(VALUE io, VALUE str, VALUE opts)
2674
io_read_nonblock(VALUE io, VALUE length, VALUE str, VALUE ex)
2693 2675
{
2694 2676
    rb_io_t *fptr;
2695
    long n;
2677
    long n, len;
2678
    struct read_internal_arg arg;
2696 2679

  
2697
    if (!RB_TYPE_P(str, T_STRING))
2698
	str = rb_obj_as_string(str);
2680
    if ((len = NUM2LONG(length)) < 0) {
2681
	rb_raise(rb_eArgError, "negative length %ld given", len);
2682
    }
2699 2683

  
2700
    io = GetWriteIO(io);
2684
    io_setstrbuf(&str,len);
2685
    OBJ_TAINT(str);
2701 2686
    GetOpenFile(io, fptr);
2702
    rb_io_check_writable(fptr);
2687
    rb_io_check_byte_readable(fptr);
2703 2688

  
2704
    if (io_fflush(fptr) < 0)
2705
        rb_sys_fail(0);
2689
    if (len == 0)
2690
	return str;
2706 2691

  
2707
    rb_io_set_nonblock(fptr);
2708
    n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
2692
    n = read_buffered_data(RSTRING_PTR(str), len, fptr);
2693
    if (n <= 0) {
2694
	rb_io_set_nonblock(fptr);
2695
	io_setstrbuf(&str, len);
2696
	arg.fd = fptr->fd;
2697
	arg.str_ptr = RSTRING_PTR(str);
2698
	arg.len = len;
2699
	rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
2700
	n = arg.len;
2701
        if (n < 0) {
2702
            if ((errno == EWOULDBLOCK || errno == EAGAIN)) {
2703
                if (ex == Qfalse) return sym_wait_readable;
2704
                rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block");
2705
            }
2706
            rb_sys_fail_path(fptr->pathv);
2707
        }
2708
    }
2709
    io_set_read_length(str, n);
2709 2710

  
2710
    if (n == -1) {
2711
        if (errno == EWOULDBLOCK || errno == EAGAIN) {
2712
	    if (no_exception_p(opts)) {
2713
		return sym_wait_writable;
2714
	    }
2715
	    else {
2716
		rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
2717
	    }
2718
	}
2719
        rb_sys_fail_path(fptr->pathv);
2711
    if (n == 0) {
2712
	if (ex == Qfalse) return Qnil;
2713
	rb_eof_error();
2720 2714
    }
2721 2715

  
2722
    return LONG2FIX(n);
2716
    return str;
2723 2717
}
2724 2718

  
2725 2719
/*
......
2779 2773
 *  return the symbol :wait_writable instead.
2780 2774
 *
2781 2775
 */
2782

  
2783 2776
static VALUE
2784
rb_io_write_nonblock(int argc, VALUE *argv, VALUE io)
2777
io_write_nonblock(VALUE io, VALUE str, VALUE ex)
2785 2778
{
2786
    VALUE str, opts;
2779
    rb_io_t *fptr;
2780
    long n;
2787 2781

  
2788
    rb_scan_args(argc, argv, "10:", &str, &opts);
2782
    if (!RB_TYPE_P(str, T_STRING))
2783
	str = rb_obj_as_string(str);
2789 2784

  
2790
    return io_write_nonblock(io, str, opts);
2785
    io = GetWriteIO(io);
2786
    GetOpenFile(io, fptr);
2787
    rb_io_check_writable(fptr);
2788

  
2789
    if (io_fflush(fptr) < 0)
2790
        rb_sys_fail(0);
2791

  
2792
    rb_io_set_nonblock(fptr);
2793
    n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
2794

  
2795
    if (n == -1) {
2796
        if (errno == EWOULDBLOCK || errno == EAGAIN) {
2797
	    if (ex == Qfalse) {
2798
		return sym_wait_writable;
2799
	    }
2800
	    else {
2801
		rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
2802
	    }
2803
	}
2804
        rb_sys_fail_path(fptr->pathv);
2805
    }
2806

  
2807
    return LONG2FIX(n);
2791 2808
}
2792 2809

  
2793 2810
/*
......
12246 12263

  
12247 12264
    rb_define_method(rb_cIO, "readlines",  rb_io_readlines, -1);
12248 12265

  
12249
    rb_define_method(rb_cIO, "read_nonblock",  io_read_nonblock, -1);
12250
    rb_define_method(rb_cIO, "write_nonblock", rb_io_write_nonblock, -1);
12266
    rb_define_private_method(rb_cIO, "__read_nonblock", io_read_nonblock, 3);
12267
    rb_define_private_method(rb_cIO, "__write_nonblock", io_write_nonblock, 2);
12251 12268
    rb_define_method(rb_cIO, "readpartial",  io_readpartial, -1);
12252 12269
    rb_define_method(rb_cIO, "read",  io_read, -1);
12253 12270
    rb_define_method(rb_cIO, "write", io_write_m, 1);
prelude.rb
13 13
    }
14 14
  end
15 15
end
16

  
17
class IO
18
  def read_nonblock(len, buf = nil, exception: true)
19
    __read_nonblock(len, buf, exception)
20
  end
21

  
22
  def write_nonblock(buf, exception: true)
23
    __write_nonblock(buf, exception)
24
  end
25
end
16
-