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

ruby-changes:39187

From: ngoto <ko1@a...>
Date: Thu, 16 Jul 2015 22:06:24 +0900 (JST)
Subject: [ruby-changes:39187] ngoto:r51268 (trunk): * process.c (redirect_dup2): when the new FD of dup2() coflicts

ngoto	2015-07-16 22:06:13 +0900 (Thu, 16 Jul 2015)

  New Revision: 51268

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51268

  Log:
    * process.c (redirect_dup2): when the new FD of dup2() coflicts
      with one of the timer thread FDs, the internal FD is diverted.
      [Bug #11336] [ruby-core:69886] [Bug #11350] [ruby-core:69961]
        
    * process.c (dup2_with_divert): new function for the above purpose.
       
    * thread_pthread.c (rb_divert_reserved_fd): new function for
      diverting reserved FD. If the given FD is the same as one of the
      reserved FDs, the reserved FD number is internally changed.
      It returns -1 when error. Otherwise, returns 0. It also returns
      0 if there is no need to change reserved FD number.
    
    * thread_win32.c (rb_divert_reserved_fd): always returns 0 because
      of no reserved FDs.
    
    * internal.h (rb_divert_reserved_fd): prototype declaration.
      It is Ruby internal use only.

  Modified files:
    trunk/ChangeLog
    trunk/internal.h
    trunk/process.c
    trunk/thread_pthread.c
    trunk/thread_win32.c
Index: thread_win32.c
===================================================================
--- thread_win32.c	(revision 51267)
+++ thread_win32.c	(revision 51268)
@@ -788,6 +788,12 @@ rb_reserved_fd_p(int fd) https://github.com/ruby/ruby/blob/trunk/thread_win32.c#L788
     return 0;
 }
 
+int
+rb_divert_reserved_fd(int fd)
+{
+    return 0;
+}
+
 rb_nativethread_id_t
 rb_nativethread_self(void)
 {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51267)
+++ ChangeLog	(revision 51268)
@@ -1,3 +1,23 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jul 16 21:47:47 2015  Naohisa Goto  <ngotogenome@g...>
+
+	* process.c (redirect_dup2): when the new FD of dup2() coflicts
+	  with one of the timer thread FDs, the internal FD is diverted.
+	  [Bug #11336] [ruby-core:69886] [Bug #11350] [ruby-core:69961]
+
+	* process.c (dup2_with_divert): new function for the above purpose.
+
+	* thread_pthread.c (rb_divert_reserved_fd): new function for
+	  diverting reserved FD. If the given FD is the same as one of the
+	  reserved FDs, the reserved FD number is internally changed.
+	  It returns -1 when error. Otherwise, returns 0. It also returns
+	  0 if there is no need to change reserved FD number.
+
+	* thread_win32.c (rb_divert_reserved_fd): always returns 0 because
+	  of no reserved FDs.
+
+	* internal.h (rb_divert_reserved_fd): prototype declaration.
+	  It is Ruby internal use only.
+
 Thu Jul 16 21:47:46 2015  Koichi Sasada  <ko1@a...>
 
 	* iseq.c (rb_iseq_disasm): rename rb_iseq_t *iseqdat to iseq
Index: thread_pthread.c
===================================================================
--- thread_pthread.c	(revision 51267)
+++ thread_pthread.c	(revision 51268)
@@ -1707,6 +1707,29 @@ rb_reserved_fd_p(int fd) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1707
 #endif
 }
 
+int
+rb_divert_reserved_fd(int fd)
+{
+#if USE_SLEEPY_TIMER_THREAD
+    int *ptr;
+    int newfd;
+
+    if ((fd == *(ptr = &(timer_thread_pipe.normal[0])) ||
+         fd == *(ptr = &(timer_thread_pipe.normal[1])) ||
+         fd == *(ptr = &(timer_thread_pipe.low[0])) ||
+         fd == *(ptr = &(timer_thread_pipe.low[1]))) &&
+        timer_thread_pipe.owner_process == getpid()) { /* async-signal-safe */
+        newfd = rb_cloexec_dup(fd); /* async-signal-safe if no error */
+        if (newfd == -1) return -1;
+        rb_update_max_fd(newfd); /* async-signal-safe if no error */
+        /* set_nonblock(newfd); */ /* async-signal-safe if no error */
+        *ptr = newfd;
+        rb_thread_wakeup_timer_thread_low(); /* async-signal-safe? */
+    }
+#endif
+    return 0;
+}
+
 rb_nativethread_id_t
 rb_nativethread_self(void)
 {
Index: process.c
===================================================================
--- process.c	(revision 51267)
+++ process.c	(revision 51268)
@@ -305,6 +305,16 @@ close_unless_reserved(int fd) https://github.com/ruby/ruby/blob/trunk/process.c#L305
     return close(fd); /* async-signal-safe */
 }
 
+static inline int
+dup2_with_divert(int oldfd, int newfd)
+{
+    if (rb_divert_reserved_fd(newfd) == -1) { /* async-signal-safe if no error occurred */
+        return -1;
+    } else {
+        return dup2(oldfd, newfd); /* async-signal-safe */
+    }
+}
+
 /*#define DEBUG_REDIRECT*/
 #if defined(DEBUG_REDIRECT)
 
@@ -344,7 +354,7 @@ static int https://github.com/ruby/ruby/blob/trunk/process.c#L354
 redirect_dup2(int oldfd, int newfd)
 {
     int ret;
-    ret = dup2(oldfd, newfd);
+    ret = dup2_with_divert(oldfd, newfd);
     ttyprintf("dup2(%d, %d) => %d\n", oldfd, newfd, ret);
     return ret;
 }
@@ -378,7 +388,7 @@ parent_redirect_close(int fd) https://github.com/ruby/ruby/blob/trunk/process.c#L388
 
 #else
 #define redirect_dup(oldfd) dup(oldfd)
-#define redirect_dup2(oldfd, newfd) dup2((oldfd), (newfd))
+#define redirect_dup2(oldfd, newfd) dup2_with_divert((oldfd), (newfd))
 #define redirect_close(fd) close_unless_reserved(fd)
 #define parent_redirect_open(pathname, flags, perm) rb_cloexec_open((pathname), (flags), (perm))
 #define parent_redirect_close(fd) close_unless_reserved(fd)
Index: internal.h
===================================================================
--- internal.h	(revision 51267)
+++ internal.h	(revision 51268)
@@ -1150,6 +1150,7 @@ void ruby_kill(rb_pid_t pid, int sig); https://github.com/ruby/ruby/blob/trunk/internal.h#L1150
 
 /* thread_pthread.c, thread_win32.c */
 void Init_native_thread(void);
+int rb_divert_reserved_fd(int fd);
 
 /* transcode.c */
 extern VALUE rb_cEncodingConverter;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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