[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]