From bd8334f5f3e901a3d54d3421dffb0db8efa024a9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 13 Mar 2011 09:48:18 +0000 Subject: release GVL for filesystem operations While local filesystems are usually very fast, we are pessimistic and should prepare for worst-case scenarios. This can use rb_thread_io_blocking_region() under Ruby 1.9.3dev. --- ext/clogger_ext/blocking_helpers.h | 58 ++++++++++++++++++++++++++++++++++++++ ext/clogger_ext/clogger.c | 1 + ext/clogger_ext/extconf.rb | 2 ++ 3 files changed, 61 insertions(+) create mode 100644 ext/clogger_ext/blocking_helpers.h diff --git a/ext/clogger_ext/blocking_helpers.h b/ext/clogger_ext/blocking_helpers.h new file mode 100644 index 0000000..dd46cea --- /dev/null +++ b/ext/clogger_ext/blocking_helpers.h @@ -0,0 +1,58 @@ +#ifdef HAVE_RB_THREAD_BLOCKING_REGION +struct stat_args { const char *path; struct stat *buf; }; +static VALUE ng_stat(void *ptr) +{ + struct stat_args *a = ptr; + return (VALUE)stat(a->path, a->buf); +} +static int my_stat(const char *path, struct stat *buf) +{ + struct stat_args a; + + a.path = path; + a.buf = buf; + return (int)rb_thread_blocking_region(ng_stat, &a, RUBY_UBF_IO, 0); +} +#ifndef HAVE_RB_THREAD_IO_BLOCKING_REGION +# define rb_thread_io_blocking_region(fn,data,fd) \ + rb_thread_blocking_region((fn),(data), RUBY_UBF_IO, 0) +#endif + +struct fstat_args { int fd; struct stat *buf; }; +static VALUE ng_fstat(void *ptr) +{ + struct fstat_args *a = ptr; + return (VALUE)fstat(a->fd, a->buf); +} + +static int my_fstat(int fd, struct stat *buf) +{ + struct fstat_args a; + + a.fd = fd; + a.buf = buf; + return (int)rb_thread_io_blocking_region(ng_fstat, &a, fd); +} + +struct write_args { int fd; const void *buf; size_t count; }; +static VALUE ng_write(void *ptr) +{ + struct write_args *a = ptr; + return (VALUE)write(a->fd, a->buf, a->count); +} +static ssize_t my_write(int fd, const void *buf, size_t count) +{ + struct write_args a; + ssize_t r; + + a.fd = fd; + a.buf = buf; + a.count = count; + r = (ssize_t)rb_thread_io_blocking_region(ng_write, &a, fd); + + return r; +} +# define stat(fd,buf) my_stat((fd),(buf)) +# define fstat(fd,buf) my_fstat((fd),(buf)) +# define write(fd,buf,count) my_write((fd),(buf),(count)) +#endif diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c index 1641f48..0adefa4 100644 --- a/ext/clogger_ext/clogger.c +++ b/ext/clogger_ext/clogger.c @@ -19,6 +19,7 @@ #include #include "ruby_1_9_compat.h" #include "broken_system_compat.h" +#include "blocking_helpers.h" /* * Availability of a monotonic clock needs to be detected at runtime diff --git a/ext/clogger_ext/extconf.rb b/ext/clogger_ext/extconf.rb index 85f2d30..27f07d0 100644 --- a/ext/clogger_ext/extconf.rb +++ b/ext/clogger_ext/extconf.rb @@ -22,6 +22,8 @@ begin have_func('localtime_r', 'time.h') or raise "localtime_r needed" have_func('gmtime_r', 'time.h') or raise "gmtime_r needed" have_func('rb_str_set_len', 'ruby.h') + have_func('rb_thread_blocking_region', 'ruby.h') + have_func('rb_thread_io_blocking_region', 'ruby.h') dir_config('clogger_ext') create_makefile('clogger_ext') rescue Object => err -- cgit v1.2.3-24-ge0c7