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

ruby-changes:48481

From: normal <ko1@a...>
Date: Wed, 1 Nov 2017 09:17:22 +0900 (JST)
Subject: [ruby-changes:48481] normal:r60595 (trunk): dir: Dir.mkdir and Dir.rmdir release GVL

normal	2017-11-01 09:17:11 +0900 (Wed, 01 Nov 2017)

  New Revision: 60595

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

  Log:
    dir: Dir.mkdir and Dir.rmdir release GVL
    
    This avoids blocking the entire VM when operating on slow or
    unreliable filesystems.  Instead, only the thread performing
    the mkdir or rmdir operation is blocked and other threads
    are free to proceed.
    
    * dir.c (nogvl_mkdir): new function
      (nogvl_rmdir): ditto
      (dir_s_mkdir): release GVL
      (dir_s_rmdir): ditto

  Modified files:
    trunk/dir.c
Index: dir.c
===================================================================
--- dir.c	(revision 60594)
+++ dir.c	(revision 60595)
@@ -1199,6 +1199,19 @@ dir_s_chroot(VALUE dir, VALUE path) https://github.com/ruby/ruby/blob/trunk/dir.c#L1199
 #define dir_s_chroot rb_f_notimplement
 #endif
 
+struct mkdir_arg {
+    const char *path;
+    mode_t mode;
+};
+
+static void *
+nogvl_mkdir(void *ptr)
+{
+    struct mkdir_arg *m = ptr;
+
+    return (void *)(VALUE)mkdir(m->path, m->mode);
+}
+
 /*
  *  call-seq:
  *     Dir.mkdir( string [, integer] ) -> 0
@@ -1217,23 +1230,34 @@ dir_s_chroot(VALUE dir, VALUE path) https://github.com/ruby/ruby/blob/trunk/dir.c#L1230
 static VALUE
 dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
 {
+    struct mkdir_arg m;
     VALUE path, vmode;
-    mode_t mode;
+    int r;
 
     if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
-	mode = NUM2MODET(vmode);
+	m.mode = NUM2MODET(vmode);
     }
     else {
-	mode = 0777;
+	m.mode = 0777;
     }
 
     path = check_dirname(path);
-    if (mkdir(RSTRING_PTR(path), mode) == -1)
+    m.path = RSTRING_PTR(path);
+    r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_mkdir, &m, RUBY_UBF_IO, 0);
+    if (r < 0)
 	rb_sys_fail_path(path);
 
     return INT2FIX(0);
 }
 
+static void *
+nogvl_rmdir(void *ptr)
+{
+    const char *path = ptr;
+
+    return (void *)(VALUE)rmdir(path);
+}
+
 /*
  *  call-seq:
  *     Dir.delete( string ) -> 0
@@ -1246,8 +1270,13 @@ dir_s_mkdir(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/dir.c#L1270
 static VALUE
 dir_s_rmdir(VALUE obj, VALUE dir)
 {
+    const char *p;
+    int r;
+
     dir = check_dirname(dir);
-    if (rmdir(RSTRING_PTR(dir)) < 0)
+    p = RSTRING_PTR(dir);
+    r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, p, RUBY_UBF_IO, 0);
+    if (r < 0)
 	rb_sys_fail_path(dir);
 
     return INT2FIX(0);

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

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