ruby-changes:32627
From: nobu <ko1@a...>
Date: Sat, 25 Jan 2014 14:50:51 +0900 (JST)
Subject: [ruby-changes:32627] nobu:r44706 (trunk): process.c: avoid EINTR from Process.spawn
nobu 2014-01-25 14:50:44 +0900 (Sat, 25 Jan 2014) New Revision: 44706 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44706 Log: process.c: avoid EINTR from Process.spawn * process.c (send_child_error): retry write on EINTR to fix occasional Errno::EINTR from Process.spawn. * process.c (recv_child_error): retry read on EINTR to fix occasional Errno::EINTR from Process.spawn. Modified files: trunk/ChangeLog trunk/process.c Index: ChangeLog =================================================================== --- ChangeLog (revision 44705) +++ ChangeLog (revision 44706) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Jan 25 14:50:42 2014 Eric Wong <normalperson@y...> + + * process.c (send_child_error): retry write on EINTR to fix + occasional Errno::EINTR from Process.spawn. + + * process.c (recv_child_error): retry read on EINTR to fix + occasional Errno::EINTR from Process.spawn. + Sat Jan 25 14:21:06 2014 Nobuyoshi Nakada <nobu@r...> * compile.c (iseq_compile_each): result of assignment should be Index: process.c =================================================================== --- process.c (revision 44705) +++ process.c (revision 44706) @@ -3296,6 +3296,30 @@ retry_fork(int *status, int *ep, int chf https://github.com/ruby/ruby/blob/trunk/process.c#L3296 } } +static ssize_t +write_retry(int fd, const void *buf, size_t len) +{ + ssize_t w; + + do { + w = write(fd, buf, len); + } while (w < 0 && errno == EINTR); + + return w; +} + +static ssize_t +read_retry(int fd, void *buf, size_t len) +{ + ssize_t r; + + do { + r = read(fd, buf, len); + } while (r < 0 && errno == EINTR); + + return r; +} + static void send_child_error(int fd, int state, char *errmsg, size_t errmsg_buflen, int chfunc_is_async_signal_safe) { @@ -3303,7 +3327,7 @@ send_child_error(int fd, int state, char https://github.com/ruby/ruby/blob/trunk/process.c#L3327 int err; if (!chfunc_is_async_signal_safe) { - if (write(fd, &state, sizeof(state)) == sizeof(state) && state) { + if (write_retry(fd, &state, sizeof(state)) == sizeof(state) && state) { VALUE errinfo = rb_errinfo(); io = rb_io_fdopen(fd, O_WRONLY|O_BINARY, NULL); rb_marshal_dump(errinfo, io); @@ -3311,11 +3335,11 @@ send_child_error(int fd, int state, char https://github.com/ruby/ruby/blob/trunk/process.c#L3335 } } err = errno; - if (write(fd, &err, sizeof(err)) < 0) err = errno; + if (write_retry(fd, &err, sizeof(err)) < 0) err = errno; if (errmsg && 0 < errmsg_buflen) { errmsg[errmsg_buflen-1] = '\0'; errmsg_buflen = strlen(errmsg); - if (errmsg_buflen > 0 && write(fd, errmsg, errmsg_buflen) < 0) + if (errmsg_buflen > 0 && write_retry(fd, errmsg, errmsg_buflen) < 0) err = errno; } if (!NIL_P(io)) rb_io_close(io); @@ -3329,7 +3353,7 @@ recv_child_error(int fd, int *statep, VA https://github.com/ruby/ruby/blob/trunk/process.c#L3353 ssize_t size; VALUE exc = Qnil; if (!chfunc_is_async_signal_safe) { - if ((read(fd, &state, sizeof(state))) == sizeof(state) && state) { + if ((read_retry(fd, &state, sizeof(state))) == sizeof(state) && state) { io = rb_io_fdopen(fd, O_RDONLY|O_BINARY, NULL); exc = rb_marshal_load(io); rb_set_errinfo(exc); @@ -3339,11 +3363,8 @@ recv_child_error(int fd, int *statep, VA https://github.com/ruby/ruby/blob/trunk/process.c#L3363 } #define READ_FROM_CHILD(ptr, len) \ (NIL_P(io) ? read(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len))) - while ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) { + if ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) { err = errno; - if (err != EINTR) { - break; - } } *errp = err; if (size == sizeof(err) && -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/