From 1daa624d56002b8b0412ccc65de460bec96c23c3 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 28 Feb 2018 05:17:01 +0000 Subject: file.c: get rid of useless conversion * file.c (rb_file_s_stat): File.stat does not accept an IO object as trying conversion to path name string first. skip conversion to IO and try stat(2) only. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- file.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'file.c') diff --git a/file.c b/file.c index 9c777ca2b7..a1ee7f4897 100644 --- a/file.c +++ b/file.c @@ -1082,6 +1082,17 @@ no_gvl_fstat(void *data) return (VALUE)fstat(arg->file.fd, arg->st); } +static int +fstat_without_gvl(int fd, struct stat *st) +{ + no_gvl_stat_data data; + + data.file.fd = fd; + data.st = st; + + return (int)(VALUE)rb_thread_io_blocking_region(no_gvl_fstat, &data, fd); +} + static void * no_gvl_stat(void * data) { @@ -1090,27 +1101,38 @@ no_gvl_stat(void * data) } static int -rb_stat(VALUE file, struct stat *st) +stat_without_gvl(const char *path, struct stat *st) { - VALUE tmp; - VALUE result; no_gvl_stat_data data; + data.file.path = path; data.st = st; + + return (int)(VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data, + RUBY_UBF_IO, NULL); +} + +static int +rb_stat(VALUE file, struct stat *st) +{ + VALUE tmp; + int result; + tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io); if (!NIL_P(tmp)) { rb_io_t *fptr; GetOpenFile(tmp, fptr); - data.file.fd = fptr->fd; - result = rb_thread_io_blocking_region(no_gvl_fstat, &data, fptr->fd); - return (int)result; + result = fstat_without_gvl(fptr->fd, st); + file = tmp; + } + else { + FilePathValue(file); + file = rb_str_encode_ospath(file); + result = stat_without_gvl(RSTRING_PTR(file), st); } - FilePathValue(file); - file = rb_str_encode_ospath(file); - data.file.path = StringValueCStr(file); - result = (VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data, RUBY_UBF_IO, NULL); - return (int)result; + RB_GC_GUARD(file); + return result; } /* @@ -1130,7 +1152,8 @@ rb_file_s_stat(VALUE klass, VALUE fname) struct stat st; FilePathValue(fname); - if (rb_stat(fname, &st) < 0) { + fname = rb_str_encode_ospath(fname); + if (stat_without_gvl(RSTRING_PTR(fname), &st) < 0) { rb_sys_fail_path(fname); } return rb_stat_new(&st); -- cgit v1.2.3