summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-26 17:31:33 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-26 17:31:33 +0000
commit506ee0c16033dde58d53a34876c762750598dad8 (patch)
tree0fd23ede280b9c3ed90d0bad01a0142af3ab059d /io.c
parentf2d84ac8a1a142e467ffce908bb627e840b9dce4 (diff)
merge revision(s) 39687,39776,40438: [Backport #8064]
* io.c (rb_update_max_fd): use ATOMIC_CAS because this function is used from timer thread too. * io.c (rb_fd_fix_cloexec): use rb_update_max_fd(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/io.c b/io.c
index ada5d9b523..752de2cad5 100644
--- a/io.c
+++ b/io.c
@@ -19,6 +19,7 @@
#include "id.h"
#include <ctype.h>
#include <errno.h>
+#include "ruby_atomic.h"
#define free(x) xfree(x)
@@ -158,15 +159,20 @@ struct argf {
int8_t init_p, next_p, binmode;
};
-static int max_file_descriptor = NOFILE;
+static rb_atomic_t max_file_descriptor = NOFILE;
void
rb_update_max_fd(int fd)
{
struct stat buf;
+ rb_atomic_t afd = (rb_atomic_t)fd;
+
if (fstat(fd, &buf) != 0 && errno == EBADF) {
rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd);
}
- if (max_file_descriptor < fd) max_file_descriptor = fd;
+
+ while (max_file_descriptor < afd) {
+ ATOMIC_CAS(max_file_descriptor, max_file_descriptor, afd);
+ }
}
void
@@ -196,7 +202,7 @@ void
rb_fd_fix_cloexec(int fd)
{
rb_maygvl_fd_fix_cloexec(fd);
- if (max_file_descriptor < fd) max_file_descriptor = fd;
+ rb_update_max_fd(fd);
}
int
@@ -5607,7 +5613,7 @@ void
rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
{
int fd, ret;
- int max = max_file_descriptor;
+ int max = (int)max_file_descriptor;
#ifdef F_MAXFD
/* F_MAXFD is available since NetBSD 2.0. */
ret = fcntl(0, F_MAXFD); /* async-signal-safe */