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/