Skip to content

Commit 05558c9

Browse files
committed
merge revision(s) 44687,44706,44727: [Backport ruby#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 rubyGH-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 ruby#8770]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@45061 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 5b05fa5 commit 05558c9

3 files changed

Lines changed: 44 additions & 6 deletions

File tree

ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
Thu Feb 20 12:58:45 2014 Tanaka Akira <akr@fsij.org>
2+
3+
* process.c (READ_FROM_CHILD): Apply the last hunk of
4+
0001-process.c-avoid-EINTR-from-Process.spawn.patch written by
5+
Eric Wong in [Bug #8770].
6+
7+
Thu Feb 20 12:58:45 2014 Eric Wong <normalperson@yhbt.net>
8+
9+
* process.c (send_child_error): retry write on EINTR to fix
10+
occasional Errno::EINTR from Process.spawn.
11+
12+
* process.c (recv_child_error): retry read on EINTR to fix
13+
occasional Errno::EINTR from Process.spawn.
14+
115
Thu Feb 20 12:24:59 2014 Eric Hodel <drbrain@segment7.net>
216

317
* lib/rinda/ring.rb (Rinda::RingFinger#make_socket): Use

process.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3296,26 +3296,50 @@ retry_fork(int *status, int *ep, int chfunc_is_async_signal_safe)
32963296
}
32973297
}
32983298

3299+
static ssize_t
3300+
write_retry(int fd, const void *buf, size_t len)
3301+
{
3302+
ssize_t w;
3303+
3304+
do {
3305+
w = write(fd, buf, len);
3306+
} while (w < 0 && errno == EINTR);
3307+
3308+
return w;
3309+
}
3310+
3311+
static ssize_t
3312+
read_retry(int fd, void *buf, size_t len)
3313+
{
3314+
ssize_t r;
3315+
3316+
do {
3317+
r = read(fd, buf, len);
3318+
} while (r < 0 && errno == EINTR);
3319+
3320+
return r;
3321+
}
3322+
32993323
static void
33003324
send_child_error(int fd, int state, char *errmsg, size_t errmsg_buflen, int chfunc_is_async_signal_safe)
33013325
{
33023326
VALUE io = Qnil;
33033327
int err;
33043328

33053329
if (!chfunc_is_async_signal_safe) {
3306-
if (write(fd, &state, sizeof(state)) == sizeof(state) && state) {
3330+
if (write_retry(fd, &state, sizeof(state)) == sizeof(state) && state) {
33073331
VALUE errinfo = rb_errinfo();
33083332
io = rb_io_fdopen(fd, O_WRONLY|O_BINARY, NULL);
33093333
rb_marshal_dump(errinfo, io);
33103334
rb_io_flush(io);
33113335
}
33123336
}
33133337
err = errno;
3314-
if (write(fd, &err, sizeof(err)) < 0) err = errno;
3338+
if (write_retry(fd, &err, sizeof(err)) < 0) err = errno;
33153339
if (errmsg && 0 < errmsg_buflen) {
33163340
errmsg[errmsg_buflen-1] = '\0';
33173341
errmsg_buflen = strlen(errmsg);
3318-
if (errmsg_buflen > 0 && write(fd, errmsg, errmsg_buflen) < 0)
3342+
if (errmsg_buflen > 0 && write_retry(fd, errmsg, errmsg_buflen) < 0)
33193343
err = errno;
33203344
}
33213345
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
33293353
ssize_t size;
33303354
VALUE exc = Qnil;
33313355
if (!chfunc_is_async_signal_safe) {
3332-
if ((read(fd, &state, sizeof(state))) == sizeof(state) && state) {
3356+
if ((read_retry(fd, &state, sizeof(state))) == sizeof(state) && state) {
33333357
io = rb_io_fdopen(fd, O_RDONLY|O_BINARY, NULL);
33343358
exc = rb_marshal_load(io);
33353359
rb_set_errinfo(exc);
@@ -3338,7 +3362,7 @@ recv_child_error(int fd, int *statep, VALUE *excp, int *errp, char *errmsg, size
33383362
*excp = exc;
33393363
}
33403364
#define READ_FROM_CHILD(ptr, len) \
3341-
(NIL_P(io) ? read(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
3365+
(NIL_P(io) ? read_retry(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
33423366
if ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) {
33433367
err = errno;
33443368
}

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.1.1"
22
#define RUBY_RELEASE_DATE "2014-02-20"
3-
#define RUBY_PATCHLEVEL 37
3+
#define RUBY_PATCHLEVEL 38
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 2

0 commit comments

Comments
 (0)