зеркало из https://github.com/github/ruby.git
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:
Родитель
d7a38817da
Коммит
17dd212f00
55
file.c
55
file.c
|
@ -1414,12 +1414,53 @@ eaccess(const char *path, int mode)
|
|||
}
|
||||
#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 fname)
|
|||
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 fname)
|
|||
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 fname)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче