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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e63dd598a7
commit
f5f6232399
39
dir.c
39
dir.c
@ -1199,6 +1199,19 @@ dir_s_chroot(VALUE dir, VALUE path)
|
|||||||
#define dir_s_chroot rb_f_notimplement
|
#define dir_s_chroot rb_f_notimplement
|
||||||
#endif
|
#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:
|
* call-seq:
|
||||||
* Dir.mkdir( string [, integer] ) -> 0
|
* Dir.mkdir( string [, integer] ) -> 0
|
||||||
@ -1217,23 +1230,34 @@ dir_s_chroot(VALUE dir, VALUE path)
|
|||||||
static VALUE
|
static VALUE
|
||||||
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
|
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
|
||||||
{
|
{
|
||||||
|
struct mkdir_arg m;
|
||||||
VALUE path, vmode;
|
VALUE path, vmode;
|
||||||
mode_t mode;
|
int r;
|
||||||
|
|
||||||
if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
|
if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
|
||||||
mode = NUM2MODET(vmode);
|
m.mode = NUM2MODET(vmode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mode = 0777;
|
m.mode = 0777;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = check_dirname(path);
|
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);
|
rb_sys_fail_path(path);
|
||||||
|
|
||||||
return INT2FIX(0);
|
return INT2FIX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
nogvl_rmdir(void *ptr)
|
||||||
|
{
|
||||||
|
const char *path = ptr;
|
||||||
|
|
||||||
|
return (void *)(VALUE)rmdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Dir.delete( string ) -> 0
|
* Dir.delete( string ) -> 0
|
||||||
@ -1246,8 +1270,13 @@ dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
|
|||||||
static VALUE
|
static VALUE
|
||||||
dir_s_rmdir(VALUE obj, VALUE dir)
|
dir_s_rmdir(VALUE obj, VALUE dir)
|
||||||
{
|
{
|
||||||
|
const char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
dir = check_dirname(dir);
|
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);
|
rb_sys_fail_path(dir);
|
||||||
|
|
||||||
return INT2FIX(0);
|
return INT2FIX(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user