[前][次][番号順一覧][スレッド一覧]

ruby-changes:70789

From: Samuel <ko1@a...>
Date: Sat, 8 Jan 2022 20:03:41 +0900 (JST)
Subject: [ruby-changes:70789] 0ca00e2cb7 (master): Move IO write buffer allocation into function.

https://git.ruby-lang.org/ruby.git/commit/?id=0ca00e2cb7

From 0ca00e2cb74f9d07d27844d97c29c208caab95a7 Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Sun, 9 Jan 2022 00:03:16 +1300
Subject: Move IO write buffer allocation into function.

---
 io.c | 218 +++++++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 119 insertions(+), 99 deletions(-)

diff --git a/io.c b/io.c
index 095013d39ef..179ccc06449 100644
--- a/io.c
+++ b/io.c
@@ -1646,6 +1646,19 @@ io_binwrite_string(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L1646
 }
 #endif
 
+inline static void
+io_allocate_write_buffer(rb_io_t *fptr, int sync)
+{
+    if (fptr->wbuf.ptr == NULL && !(sync && (fptr->mode & FMODE_SYNC))) {
+        fptr->wbuf.off = 0;
+        fptr->wbuf.len = 0;
+        fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
+        fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
+        fptr->write_lock = rb_mutex_new();
+        rb_mutex_allow_trap(fptr->write_lock, 1);
+    }
+}
+
 static long
 io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
 {
@@ -1656,14 +1669,7 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync) https://github.com/ruby/ruby/blob/trunk/io.c#L1669
 
     if ((n = len) <= 0) return n;
 
-    if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
-        fptr->wbuf.off = 0;
-        fptr->wbuf.len = 0;
-        fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
-        fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
-        fptr->write_lock = rb_mutex_new();
-        rb_mutex_allow_trap(fptr->write_lock, 1);
-    }
+    io_allocate_write_buffer(fptr, !nosync);
 
     if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
         (fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
@@ -1865,78 +1871,79 @@ io_binwritev(struct iovec *iov, int iovcnt, rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L1871
     if (iovcnt == 0) return 0;
     for (i = 1; i < iovcnt; i++) total += iov[i].iov_len;
 
-    if (fptr->wbuf.ptr == NULL && !(fptr->mode & FMODE_SYNC)) {
-	fptr->wbuf.off = 0;
-	fptr->wbuf.len = 0;
-	fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
-	fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
-	fptr->write_lock = rb_mutex_new();
-	rb_mutex_allow_trap(fptr->write_lock, 1);
-    }
+    io_allocate_write_buffer(fptr, 1);
 
     if (fptr->wbuf.ptr && fptr->wbuf.len) {
-	long offset = fptr->wbuf.off + fptr->wbuf.len;
-	if (offset + total <= fptr->wbuf.capa) {
-	    for (i = 1; i < iovcnt; i++) {
-		memcpy(fptr->wbuf.ptr+offset, iov[i].iov_base, iov[i].iov_len);
-		offset += iov[i].iov_len;
-	    }
-	    fptr->wbuf.len += total;
-	    return total;
-	}
-	else {
-	    iov[0].iov_base = fptr->wbuf.ptr + fptr->wbuf.off;
-	    iov[0].iov_len  = fptr->wbuf.len;
-	}
+        long offset = fptr->wbuf.off + fptr->wbuf.len;
+        if (offset + total <= fptr->wbuf.capa) {
+            for (i = 1; i < iovcnt; i++) {
+                memcpy(fptr->wbuf.ptr+offset, iov[i].iov_base, iov[i].iov_len);
+                offset += iov[i].iov_len;
+            }
+
+            fptr->wbuf.len += total;
+            return total;
+        }
+        else {
+            iov[0].iov_base = fptr->wbuf.ptr + fptr->wbuf.off;
+            iov[0].iov_len  = fptr->wbuf.len;
+        }
     }
     else {
-	iov++;
-	if (!--iovcnt) return 0;
+        iov++;
+        if (!--iovcnt) return 0;
     }
 
   retry:
     if (fptr->write_lock) {
-	struct binwritev_arg arg;
-	arg.fptr = fptr;
-	arg.iov  = iov;
-	arg.iovcnt = iovcnt;
-	r = rb_mutex_synchronize(fptr->write_lock, call_writev_internal, (VALUE)&arg);
+        struct binwritev_arg arg;
+        arg.fptr = fptr;
+        arg.iov  = iov;
+        arg.iovcnt = iovcnt;
+        r = rb_mutex_synchronize(fptr->write_lock, call_writev_internal, (VALUE)&arg);
     }
     else {
-	r = rb_writev_internal(fptr, iov, iovcnt);
+        r = rb_writev_internal(fptr, iov, iovcnt);
     }
 
     if (r >= 0) {
-	written_len += r;
-	if (fptr->wbuf.ptr && fptr->wbuf.len) {
-	    if (written_len < fptr->wbuf.len) {
-		fptr->wbuf.off += r;
-		fptr->wbuf.len -= r;
-	    }
-	    else {
-		written_len -= fptr->wbuf.len;
-		fptr->wbuf.off = 0;
-		fptr->wbuf.len = 0;
-	    }
-	}
-	if (written_len == total) return total;
+        written_len += r;
+        if (fptr->wbuf.ptr && fptr->wbuf.len) {
+            if (written_len < fptr->wbuf.len) {
+                fptr->wbuf.off += r;
+                fptr->wbuf.len -= r;
+            }
+            else {
+                written_len -= fptr->wbuf.len;
+                fptr->wbuf.off = 0;
+                fptr->wbuf.len = 0;
+            }
+        }
 
-	while (r >= (ssize_t)iov->iov_len) {
-	    /* iovcnt > 0 */
-	    r -= iov->iov_len;
-	    iov->iov_len = 0;
-	    iov++;
-	    if (!--iovcnt) return total;
-	    /* defensive check: written_len should == total */
-	}
-	iov->iov_base = (char *)iov->iov_base + r;
-	iov->iov_len -= r;
+        if (written_len == total) return total;
 
-	errno = EAGAIN;
+        while (r >= (ssize_t)iov->iov_len) {
+            /* iovcnt > 0 */
+            r -= iov->iov_len;
+            iov->iov_len = 0;
+            iov++;
+
+            if (!--iovcnt) {
+                // assert(written_len == total);
+
+                return total;
+            }
+        }
+
+        iov->iov_base = (char *)iov->iov_base + r;
+        iov->iov_len -= r;
+
+        errno = EAGAIN;
     }
+
     if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) {
-	rb_io_check_closed(fptr);
-	goto retry;
+        rb_io_check_closed(fptr);
+        goto retry;
     }
 
     return -1L;
@@ -1954,24 +1961,26 @@ io_fwritev(int argc, const VALUE *argv, rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L1961
     tmp_array = ALLOCV_N(VALUE, v2, argc);
 
     for (i = 0; i < argc; i++) {
-	str = rb_obj_as_string(argv[i]);
-	converted = 0;
-	str = do_writeconv(str, fptr, &converted);
-	if (converted)
-	    OBJ_FREEZE(str);
+        str = rb_obj_as_string(argv[i]);
+        converted = 0;
+        str = do_writeconv(str, fptr, &converted);
 
-	tmp = rb_str_tmp_frozen_acquire(str);
-	tmp_array[i] = tmp;
-	/* iov[0] is reserved for buffer of fptr */
-	iov[i+1].iov_base = RSTRING_PTR(tmp);
-	iov[i+1].iov_len = RSTRING_LEN(tmp);
+        if (converted)
+            OBJ_FREEZE(str);
+
+        tmp = rb_str_tmp_frozen_acquire(str);
+        tmp_array[i] = tmp;
+
+        /* iov[0] is reserved for buffer of fptr */
+        iov[i+1].iov_base = RSTRING_PTR(tmp);
+        iov[i+1].iov_len = RSTRING_LEN(tmp);
     }
 
     n = io_binwritev(iov, iovcnt, fptr);
     if (v1) ALLOCV_END(v1);
 
     for (i = 0; i < argc; i++) {
-	rb_str_tmp_frozen_release(argv[i], tmp_array[i]);
+        rb_str_tmp_frozen_release(argv[i], tmp_array[i]);
     }
 
     if (v2) ALLOCV_END(v2);
@@ -2000,10 +2009,12 @@ io_writev(int argc, const VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L2009
 
     io = GetWriteIO(io);
     tmp = rb_io_check_io(io);
+
     if (NIL_P(tmp)) {
-	/* port is not IO, call write method for it. */
-	return rb_funcallv(io, id_write, argc, argv);
+        /* port is not IO, call write method for it. */
+        return rb_funcallv(io, id_write, argc, argv);
     }
+
     io = tmp;
 
     GetOpenFile(io, fptr);
@@ -2011,18 +2022,21 @@ io_writev(int argc, const VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L2022
 
     for (i = 0; i < argc; i += cnt) {
 #ifdef HAVE_WRITEV
-	if ((fptr->mode & (FMODE_SYNC|FMODE_TTY)) && iovcnt_ok(cnt = argc - i)) {
-	    n = io_fwritev(cnt, &argv[i], fptr);
-	}
-	else
+        if ((fptr->mode & (FMODE_SYNC|FMODE_TTY)) && iovcnt_ok(cnt = argc - i)) {
+            n = io_fwritev(cnt, &argv[i], fptr);
+        }
+        else
 #endif
-	{
-	    cnt = 1;
-	    /* sync at last item */
-	    n = io_fwrite(rb_obj_as_string(argv[i]), fptr, (i < argc-1));
-	}
-        if (n < 0L) rb_sys_fail_on_write(fptr);
-	total = rb_fix_plus(LONG2FIX(n), total);
+        {
+            cnt = 1;
+            /* sync at last item */
+            n = io_fwrite(rb_obj_as_string(argv[i]), fptr, (i < argc-1));
+        }
+
+        if (n < 0L)
+            rb_sys_fail_on_write(fptr);
+
+        total = rb_fix_plus(LONG2FIX(n), total);
     }
 
     return total;
@@ -2051,11 +2065,11 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L2065
 io_write_m(int argc, VALUE *argv, VALUE io)
 {
     if (argc != 1) {
-	return io_writev(argc, argv, io);
+        return io_writev(argc, argv, io);
     }
     else {
-	VALUE str = argv[0];
-	return io_write(io, str, 0);
+        VALUE str = argv[0];
+        return io_write(io, str, 0);
     }
 }
 
@@ -2069,16 +2083,22 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L2083
 rb_io_writev(VALUE io, int argc, const VALUE *argv)
 {
     if (argc > 1 && rb_obj_method_arity(io, id_write) == 1) {
-	if (io != rb_ractor_stderr() && RTEST(ruby_verbose)) {
-	    VALUE klass = CLASS_OF(io);
-	    char sep = FL_TEST(klass, FL_SINGLETON) ? (klass = io, '.') : '#';
-            rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, "%+"PRIsVALUE"%c""write is outdated interface"
-		       " which accepts just one argument",
-		       klass, sep);
-	}
-	do rb_io_write(io, *argv++); while (--argc);
-	return argv[0];		/* unused right now */
+        if (io != rb_ractor_stderr() && RTEST(ruby_verbose)) {
+            VALUE klass = CLASS_OF(io);
+            char sep = FL_TEST(klass, FL_SINGLETON) ? (klass = io, '.') : '#';
+            rb_category_warning(
+                RB_WARN_CATEGORY_DEPRECATED, "%+"PRIsVALUE"%c""write is outdated interface"
+                " which accepts just one argument",
+                klass, sep
+            );
+        }
+
+        do rb_io_write(io, *argv++); while (--argc);
+
+        /* unused right now */
+        return argv[0];
     }
+
     return rb_funcallv(io, id_write, argc, argv);
 }
 
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]