From 0b3ef899f200f4a54433d53f92fbf81f619c67d7 Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 14 Jun 2015 08:20:43 +0000 Subject: [PATCH] file.c: open without gvl * file.c (rb_file_load_ok): try opening file without gvl not to lock entire process. [Bug #11060] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ common.mk | 4 +++- file.c | 11 ++++++++++- test/ruby/test_require.rb | 13 +++++++++++++ win32/file.c | 14 +++++++++++--- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c69e165963..7abb7adfae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Jun 14 17:20:40 2015 Nobuyoshi Nakada + + * file.c (rb_file_load_ok): try opening file without gvl not to + lock entire process. [Bug #11060] + Sun Jun 14 10:43:50 2015 NAKAMURA Usaku * tool/runruby.rb: just remove the lines of RUBY_VERSION check and raise diff --git a/common.mk b/common.mk index dee73c69e7..6bf57c1d23 100644 --- a/common.mk +++ b/common.mk @@ -713,7 +713,8 @@ compile.$(OBJEXT): {$(VPATH)}opt_sc.inc {$(VPATH)}optunifs.inc win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}dln.h {$(VPATH)}dln_find.c \ {$(VPATH)}internal.h $(RUBY_H_INCLUDES) $(PLATFORM_D) -win32/file.$(OBJEXT): {$(VPATH)}win32/file.c $(RUBY_H_INCLUDES) $(PLATFORM_D) +win32/file.$(OBJEXT): {$(VPATH)}win32/file.c {$(VPATH)}thread.h \ + $(RUBY_H_INCLUDES) $(PLATFORM_D) $(NEWLINE_C): $(srcdir)/enc/trans/newline.trans $(srcdir)/tool/transcode-tblgen.rb $(Q) $(MAKEDIRS) $(@D) @@ -1439,6 +1440,7 @@ file.$(OBJEXT): {$(VPATH)}missing.h file.$(OBJEXT): {$(VPATH)}oniguruma.h file.$(OBJEXT): {$(VPATH)}st.h file.$(OBJEXT): {$(VPATH)}subst.h +file.$(OBJEXT): {$(VPATH)}thread.h file.$(OBJEXT): {$(VPATH)}util.h gc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h gc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h diff --git a/file.c b/file.c index a9444029d2..026ed031a1 100644 --- a/file.c +++ b/file.c @@ -26,6 +26,7 @@ #include "internal.h" #include "ruby/io.h" #include "ruby/util.h" +#include "ruby/thread.h" #include "dln.h" #ifdef HAVE_UNISTD_H @@ -5621,11 +5622,19 @@ rb_path_check(const char *path) } #ifndef _WIN32 +static void * +loadopen_func(void *arg) +{ + return (void *)(VALUE)rb_cloexec_open((const char *)arg, O_RDONLY, 0); +} + int rb_file_load_ok(const char *path) { int ret = 1; - int fd = rb_cloexec_open(path, O_RDONLY, 0); + int fd; + + fd = (int)(VALUE)rb_thread_call_without_gvl(loadopen_func, (void *)path, RUBY_UBF_IO, 0); if (fd == -1) return 0; rb_update_max_fd(fd); #if !defined DOSISH diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index b7797f0877..d840196e51 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -693,4 +693,17 @@ class TestRequire < Test::Unit::TestCase INPUT } end + + def test_loading_fifo_threading + Tempfile.create(%w'fifo .rb') {|f| + f.close + File.unlink(f.path) + File.mkfifo(f.path) + assert_separately(["-", f.path], <<-END, timeout: 3) + th = Thread.current + Thread.start {0.1; th.raise(IOError)} + assert_raise(IOError) {load(ARGV[0])} + END + } + end end diff --git a/win32/file.c b/win32/file.c index 6452aadaba..92b99a063e 100644 --- a/win32/file.c +++ b/win32/file.c @@ -1,5 +1,6 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" +#include "ruby/thread.h" #include "internal.h" #include #include @@ -683,6 +684,14 @@ rb_readlink(VALUE path) return append_wstr(rb_enc_str_new(0, 0, enc), wbuf, len, cp, path_cp, enc); } +static void * +loadopen_func(void *wpath) +{ + return (void *)CreateFileW(wpath, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +} + int rb_file_load_ok(const char *path) { @@ -700,9 +709,8 @@ rb_file_load_ok(const char *path) ret = 0; } else { - HANDLE h = CreateFileW(wpath, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE h = (HANDLE)rb_thread_call_without_gvl(loadopen_func, (void *)wpath, + RUBY_UBF_IO, 0); if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); }