mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
merge revision(s) 44687,44706,44727: [Backport #8770]
* process.c (recv_child_error): Fix deadlock in rb_fork_internal when a signal is sent to the parent process while Ruby is forking in IO.popen. Patch by Scott Francis. Closes GH-513. * 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. * process.c (READ_FROM_CHILD): Apply the last hunk of 0001-process.c-avoid-EINTR-from-Process.spawn.patch written by Eric Wong in [Bug #8770]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@45061 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f851d5dea6
commit
6770402812
3 changed files with 44 additions and 6 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Thu Feb 20 12:58:45 2014 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* process.c (READ_FROM_CHILD): Apply the last hunk of
|
||||
0001-process.c-avoid-EINTR-from-Process.spawn.patch written by
|
||||
Eric Wong in [Bug #8770].
|
||||
|
||||
Thu Feb 20 12:58:45 2014 Eric Wong <normalperson@yhbt.net>
|
||||
|
||||
* 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.
|
||||
|
||||
Thu Feb 20 12:24:59 2014 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* lib/rinda/ring.rb (Rinda::RingFinger#make_socket): Use
|
||||
|
|
34
process.c
34
process.c
|
@ -3296,6 +3296,30 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
|
|||
}
|
||||
}
|
||||
|
||||
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 *errmsg, size_t errmsg_buflen, int chfu
|
|||
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 *errmsg, size_t errmsg_buflen, int chfu
|
|||
}
|
||||
}
|
||||
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, VALUE *excp, int *errp, char *errmsg, size
|
|||
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);
|
||||
|
@ -3338,7 +3362,7 @@ recv_child_error(int fd, int *statep, VALUE *excp, int *errp, char *errmsg, size
|
|||
*excp = exc;
|
||||
}
|
||||
#define READ_FROM_CHILD(ptr, len) \
|
||||
(NIL_P(io) ? read(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
|
||||
(NIL_P(io) ? read_retry(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
|
||||
if ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) {
|
||||
err = errno;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define RUBY_VERSION "2.1.1"
|
||||
#define RUBY_RELEASE_DATE "2014-02-20"
|
||||
#define RUBY_PATCHLEVEL 37
|
||||
#define RUBY_PATCHLEVEL 38
|
||||
|
||||
#define RUBY_RELEASE_YEAR 2014
|
||||
#define RUBY_RELEASE_MONTH 2
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue