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

ruby-changes:48808

From: normal <ko1@a...>
Date: Tue, 28 Nov 2017 12:28:40 +0900 (JST)
Subject: [ruby-changes:48808] normal:r60925 (trunk): file: release GVL for access(2) syscalls

normal	2017-11-28 12:28:35 +0900 (Tue, 28 Nov 2017)

  New Revision: 60925

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

  Log:
    file: release GVL for access(2) syscalls
    
    Like stat(2), the access(2) syscall may take an indeterminate
    amount of time on slow/remote filesystems.
    
    This lets the following methods release the GVL to avoid choking
    the entire VM while one thread is stuck on a slow or
    non-responsive filesystem:
    
    - File.readable?
    - File.readable_real?
    - File.writable?
    - File.writable_real?
    - File.executable?
    - File.executable_real?
    
    * file.c (nogvl_eaccess): new function
      (nogvl_access): ditto
      (rb_access): new wrapper function
      (rb_eaccess): release GVL
      (rb_file_readable_real_p): use rb_access
      (rb_file_writable_real_p): ditto
      (rb_file_executable_real_p): ditto

  Modified files:
    trunk/file.c
Index: file.c
===================================================================
--- file.c	(revision 60924)
+++ file.c	(revision 60925)
@@ -1414,12 +1414,53 @@ eaccess(const char *path, int mode) https://github.com/ruby/ruby/blob/trunk/file.c#L1414
 }
 #endif
 
+struct access_arg {
+    const char *path;
+    int mode;
+};
+
+static void *
+nogvl_eaccess(void *ptr)
+{
+    struct access_arg *aa = ptr;
+
+    return (void *)(VALUE)eaccess(aa->path, aa->mode);
+}
+
 static int
 rb_eaccess(VALUE fname, int mode)
 {
+    struct access_arg aa;
+
     FilePathValue(fname);
     fname = rb_str_encode_ospath(fname);
-    return eaccess(StringValueCStr(fname), mode);
+    aa.path = StringValueCStr(fname);
+    aa.mode = mode;
+
+    return (int)(VALUE)rb_thread_call_without_gvl(nogvl_eaccess, &aa,
+						RUBY_UBF_IO, 0);
+}
+
+static void *
+nogvl_access(void *ptr)
+{
+    struct access_arg *aa = ptr;
+
+    return (void *)(VALUE)access(aa->path, aa->mode);
+}
+
+static int
+rb_access(VALUE fname, int mode)
+{
+    struct access_arg aa;
+
+    FilePathValue(fname);
+    fname = rb_str_encode_ospath(fname);
+    aa.path = StringValueCStr(fname);
+    aa.mode = mode;
+
+    return (int)(VALUE)rb_thread_call_without_gvl(nogvl_access, &aa,
+						RUBY_UBF_IO, 0);
 }
 
 /*
@@ -1680,9 +1721,7 @@ rb_file_readable_p(VALUE obj, VALUE fnam https://github.com/ruby/ruby/blob/trunk/file.c#L1721
 static VALUE
 rb_file_readable_real_p(VALUE obj, VALUE fname)
 {
-    FilePathValue(fname);
-    fname = rb_str_encode_ospath(fname);
-    if (access(StringValueCStr(fname), R_OK) < 0) return Qfalse;
+    if (rb_access(fname, R_OK) < 0) return Qfalse;
     return Qtrue;
 }
 
@@ -1750,9 +1789,7 @@ rb_file_writable_p(VALUE obj, VALUE fnam https://github.com/ruby/ruby/blob/trunk/file.c#L1789
 static VALUE
 rb_file_writable_real_p(VALUE obj, VALUE fname)
 {
-    FilePathValue(fname);
-    fname = rb_str_encode_ospath(fname);
-    if (access(StringValueCStr(fname), W_OK) < 0) return Qfalse;
+    if (rb_access(fname, W_OK) < 0) return Qfalse;
     return Qtrue;
 }
 
@@ -1812,9 +1849,7 @@ rb_file_executable_p(VALUE obj, VALUE fn https://github.com/ruby/ruby/blob/trunk/file.c#L1849
 static VALUE
 rb_file_executable_real_p(VALUE obj, VALUE fname)
 {
-    FilePathValue(fname);
-    fname = rb_str_encode_ospath(fname);
-    if (access(StringValueCStr(fname), X_OK) < 0) return Qfalse;
+    if (rb_access(fname, X_OK) < 0) return Qfalse;
     return Qtrue;
 }
 

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

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