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

ruby-changes:48972

From: normal <ko1@a...>
Date: Sat, 9 Dec 2017 12:46:43 +0900 (JST)
Subject: [ruby-changes:48972] normal:r61091 (trunk): Dir#chdir keeps GVL if passed block

normal	2017-12-09 12:46:39 +0900 (Sat, 09 Dec 2017)

  New Revision: 61091

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

  Log:
    Dir#chdir keeps GVL if passed block
    
    On further examination, Dir.chdir with a block from multiple
    threads is thread-unsafe given our use of the chdir_blocking and
    chdir_thread global variables.
    
    This bug was only introduced in r60583 so not part of any stable
    release.
    
    Dir.chdir without a block can still make senses in a MT context
    as only one thread could be cwd-sensitive and other threads do
    not care which directory they're in.
    
    * dir.c (dir_chdir): keep GVL here
      (dir_s_chdir): release GVL if no block given

  Modified files:
    trunk/dir.c
Index: dir.c
===================================================================
--- dir.c	(revision 61090)
+++ dir.c	(revision 61091)
@@ -1002,11 +1002,7 @@ nogvl_chdir(void *ptr) https://github.com/ruby/ruby/blob/trunk/dir.c#L1002
 static void
 dir_chdir(VALUE path)
 {
-    int r;
-    char *p = RSTRING_PTR(path);
-
-    r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p, RUBY_UBF_IO, 0);
-    if (r < 0)
+    if (chdir(RSTRING_PTR(path)) < 0)
 	rb_sys_fail_path(path);
 }
 
@@ -1111,7 +1107,13 @@ dir_s_chdir(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/dir.c#L1107
 	args.done = FALSE;
 	return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
     }
-    dir_chdir(path);
+    else {
+	char *p = RSTRING_PTR(path);
+	int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p,
+							RUBY_UBF_IO, 0);
+	if (r < 0)
+	    rb_sys_fail_path(path);
+    }
 
     return INT2FIX(0);
 }

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

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