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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60925 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d7a38817da
commit
17dd212f00
55
file.c
55
file.c
@ -1414,12 +1414,53 @@ eaccess(const char *path, int mode)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
static int
|
||||||
rb_eaccess(VALUE fname, int mode)
|
rb_eaccess(VALUE fname, int mode)
|
||||||
{
|
{
|
||||||
|
struct access_arg aa;
|
||||||
|
|
||||||
FilePathValue(fname);
|
FilePathValue(fname);
|
||||||
fname = rb_str_encode_ospath(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 fname)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_file_readable_real_p(VALUE obj, VALUE fname)
|
rb_file_readable_real_p(VALUE obj, VALUE fname)
|
||||||
{
|
{
|
||||||
FilePathValue(fname);
|
if (rb_access(fname, R_OK) < 0) return Qfalse;
|
||||||
fname = rb_str_encode_ospath(fname);
|
|
||||||
if (access(StringValueCStr(fname), R_OK) < 0) return Qfalse;
|
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,9 +1789,7 @@ rb_file_writable_p(VALUE obj, VALUE fname)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_file_writable_real_p(VALUE obj, VALUE fname)
|
rb_file_writable_real_p(VALUE obj, VALUE fname)
|
||||||
{
|
{
|
||||||
FilePathValue(fname);
|
if (rb_access(fname, W_OK) < 0) return Qfalse;
|
||||||
fname = rb_str_encode_ospath(fname);
|
|
||||||
if (access(StringValueCStr(fname), W_OK) < 0) return Qfalse;
|
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1812,9 +1849,7 @@ rb_file_executable_p(VALUE obj, VALUE fname)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_file_executable_real_p(VALUE obj, VALUE fname)
|
rb_file_executable_real_p(VALUE obj, VALUE fname)
|
||||||
{
|
{
|
||||||
FilePathValue(fname);
|
if (rb_access(fname, X_OK) < 0) return Qfalse;
|
||||||
fname = rb_str_encode_ospath(fname);
|
|
||||||
if (access(StringValueCStr(fname), X_OK) < 0) return Qfalse;
|
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user