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

ruby-changes:49261

From: normal <ko1@a...>
Date: Thu, 21 Dec 2017 09:26:29 +0900 (JST)
Subject: [ruby-changes:49261] normal:r61376 (trunk): io.c: IO#pwrite uses tmp buffer to avoid parallel modification

normal	2017-12-21 09:26:24 +0900 (Thu, 21 Dec 2017)

  New Revision: 61376

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61376

  Log:
    io.c: IO#pwrite uses tmp buffer to avoid parallel modification
    
    Since we release GVL, we must freeze and duplicate the string buffer
    to prevent other threads from modifying our buffer while we are
    waiting on pwrite(2).
    
    * io.c (rb_io_pwrite): use_rb_str_tmp_frozen_{acquire/release}
      [Bug #14195]

  Modified files:
    trunk/io.c
Index: io.c
===================================================================
--- io.c	(revision 61375)
+++ io.c	(revision 61376)
@@ -5186,12 +5186,11 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L5186
     rb_io_t *fptr;
     ssize_t n;
     struct prdwr_internal_arg arg;
+    VALUE tmp;
 
     if (!RB_TYPE_P(str, T_STRING))
 	str = rb_obj_as_string(str);
 
-    arg.buf = RSTRING_PTR(str);
-    arg.count = (size_t)RSTRING_LEN(str);
     arg.offset = NUM2OFFT(offset);
 
     io = GetWriteIO(io);
@@ -5199,10 +5198,13 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L5198
     rb_io_check_writable(fptr);
     arg.fd = fptr->fd;
 
-    n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
-    RB_GC_GUARD(str);
+    tmp = rb_str_tmp_frozen_acquire(str);
+    arg.buf = RSTRING_PTR(tmp);
+    arg.count = (size_t)RSTRING_LEN(tmp);
 
+    n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
     if (n == -1) rb_sys_fail_path(fptr->pathv);
+    rb_str_tmp_frozen_release(str, tmp);
 
     return SSIZET2NUM(n);
 }

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

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