ruby-changes:40646
From: normal <ko1@a...>
Date: Tue, 24 Nov 2015 06:58:14 +0900 (JST)
Subject: [ruby-changes:40646] normal:r52725 (trunk): io.c (rb_gc_for_fd): wrapper for retrying FD creation
normal 2015-11-24 06:57:24 +0900 (Tue, 24 Nov 2015) New Revision: 52725 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52725 Log: io.c (rb_gc_for_fd): wrapper for retrying FD creation This simplifies callers and makes error handling more consistent between our pipe, open, fdopen, and dup wrappers. This adds missing ENOMEM handling as documented in the open(2), pipe(2freebsd), and fdopen(3posix) manpages on my system. We also avoid repeatedly accessing `errno` which is implemented in TLS on GNU/Linux systems and more expensive to read than a local variable. We may export this in internal.h for ext/socket/* and dir.c, too. * io.c (rb_gc_for_fd): new helper function (ruby_dup): use rb_gc_for_fd (rb_sysopen): ditto (rb_fdopen): ditto (rb_pipe): ditto [ruby-core:71623] [Feature #11727] Modified files: trunk/ChangeLog trunk/io.c Index: ChangeLog =================================================================== --- ChangeLog (revision 52724) +++ ChangeLog (revision 52725) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Nov 24 06:46:27 2015 Eric Wong <e@8...> + + * io.c (rb_gc_for_fd): new helper function + (ruby_dup): use rb_gc_for_fd + (rb_sysopen): ditto + (rb_fdopen): ditto + (rb_pipe): ditto + [ruby-core:71623] [Feature #11727] + Tue Nov 24 05:13:35 2015 Eric Wong <e@8...> * ext/fiddle/function.c (struct nogvl_ffi_call_args): Index: io.c =================================================================== --- io.c (revision 52724) +++ io.c (revision 52725) @@ -885,14 +885,23 @@ rb_io_read_check(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L885 } static int +rb_gc_for_fd(int err) +{ + if (err == EMFILE || err == ENFILE || err == ENOMEM) { + rb_gc(); + return 1; + } + return 0; +} + +static int ruby_dup(int orig) { int fd; fd = rb_cloexec_dup(orig); if (fd < 0) { - if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) { - rb_gc(); + if (rb_gc_for_fd(errno)) { fd = rb_cloexec_dup(orig); } if (fd < 0) { @@ -5418,8 +5427,7 @@ rb_sysopen(VALUE fname, int oflags, mode https://github.com/ruby/ruby/blob/trunk/io.c#L5427 fd = rb_sysopen_internal(&data); if (fd < 0) { - if (errno == EMFILE || errno == ENFILE) { - rb_gc(); + if (rb_gc_for_fd(errno)) { fd = rb_sysopen_internal(&data); } if (fd < 0) { @@ -5439,15 +5447,15 @@ rb_fdopen(int fd, const char *modestr) https://github.com/ruby/ruby/blob/trunk/io.c#L5447 #endif file = fdopen(fd, modestr); if (!file) { - if ( #if defined(__sun) - errno == 0 || -#endif - errno == EMFILE || errno == ENFILE) { + if (errno == 0) { rb_gc(); -#if defined(__sun) errno = 0; + file = fdopen(fd, modestr); + } + else #endif + if (rb_gc_for_fd(errno)) { file = fdopen(fd, modestr); } if (!file) { @@ -5713,8 +5721,7 @@ rb_pipe(int *pipes) https://github.com/ruby/ruby/blob/trunk/io.c#L5721 int ret; ret = rb_cloexec_pipe(pipes); if (ret == -1) { - if (errno == EMFILE || errno == ENFILE) { - rb_gc(); + if (rb_gc_for_fd(errno)) { ret = rb_cloexec_pipe(pipes); } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/