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

ruby-changes:48714

From: normal <ko1@a...>
Date: Sat, 18 Nov 2017 11:01:49 +0900 (JST)
Subject: [ruby-changes:48714] normal:r60830 (trunk): dir: release GVL on opendir

normal	2017-11-18 11:01:44 +0900 (Sat, 18 Nov 2017)

  New Revision: 60830

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

  Log:
    dir: release GVL on opendir
    
    opendir(3) is subject to the same pathological slowdowns on
    slow or unreliable filesystems as open(2), so release the GVL
    to avoid stalling the entire VM like we do with IO#open
    
    * dir.c (nogvl_opendir): new function
      (opendir_without_gvl): new function
      (dir_initialize): s/opendir/&_without_gvl/
      (do_opendir): ditto

  Modified files:
    trunk/dir.c
Index: dir.c
===================================================================
--- dir.c	(revision 60829)
+++ dir.c	(revision 60830)
@@ -490,6 +490,24 @@ dir_s_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/dir.c#L490
     return obj;
 }
 
+static void *
+nogvl_opendir(void *ptr)
+{
+    const char *path = ptr;
+
+    return (void *)opendir(path);
+}
+
+static DIR *
+opendir_without_gvl(const char *path)
+{
+    union { const char *in; void *out; } u;
+
+    u.in = path;
+
+    return rb_thread_call_without_gvl(nogvl_opendir, u.out, RUBY_UBF_IO, 0);
+}
+
 /*
  *  call-seq:
  *     Dir.new( string ) -> aDir
@@ -536,18 +554,18 @@ dir_initialize(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/dir.c#L554
     RB_OBJ_WRITE(dir, &dp->path, Qnil);
     dp->enc = fsenc;
     path = RSTRING_PTR(dirname);
-    dp->dir = opendir(path);
+    dp->dir = opendir_without_gvl(path);
     if (dp->dir == NULL) {
 	int e = errno;
 	if (rb_gc_for_fd(e)) {
-	    dp->dir = opendir(path);
+	    dp->dir = opendir_without_gvl(path);
 	}
 #ifdef HAVE_GETATTRLIST
 	else if (e == EIO) {
 	    u_int32_t attrbuf[1];
 	    struct attrlist al = {ATTR_BIT_MAP_COUNT, 0};
 	    if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW) == 0) {
-		dp->dir = opendir(path);
+		dp->dir = opendir_without_gvl(path);
 	    }
 	}
 #endif
@@ -1411,7 +1429,7 @@ do_opendir(const int basefd, const char https://github.com/ruby/ruby/blob/trunk/dir.c#L1429
     fd = openat(basefd, path, 0, opendir_flags);
     dirp = (fd < 0) ? NULL : fdopendir(fd);
 #else
-    dirp = opendir(path);
+    dirp = opendir_without_gvl(path);
 #endif
     if (!dirp) {
 	int e = errno;
@@ -1422,7 +1440,7 @@ do_opendir(const int basefd, const char https://github.com/ruby/ruby/blob/trunk/dir.c#L1440
 		dirp = fdopendir(fd);
 	    }
 #else
-	    dirp = opendir(path);
+	    dirp = opendir_without_gvl(path);
 #endif
 	    if (dirp) break;
 	    e = errno;

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

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