From a78a9b0d17a98c3571b82f3fa1cf31d250a9dea0 Mon Sep 17 00:00:00 2001 From: akr Date: Tue, 2 Sep 2014 13:56:35 +0000 Subject: * process.c (rb_fork_async_signal_safe): Inline rb_fork_internal. (rb_fork_ruby): Ditto. (rb_fork_internal): Removed. (chfunc_protect): Removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 ++++ process.c | 116 +++++++++++++++++++++++--------------------------------------- 2 files changed, 49 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37febd2e1b..9b78f71c6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Sep 2 22:56:25 2014 Tanaka Akira + + * process.c (rb_fork_async_signal_safe): Inline rb_fork_internal. + (rb_fork_ruby): Ditto. + (rb_fork_internal): Removed. + (chfunc_protect): Removed. + Tue Sep 2 22:43:52 2014 Tanaka Akira * test/ruby/test_io.rb (test_new_with_block): Set autoclose to avoid diff --git a/process.c b/process.c index f2bf7c13af..dc4f17d537 100644 --- a/process.c +++ b/process.c @@ -2819,8 +2819,8 @@ static int run_exec_pgroup(const struct rb_execarg *eargp, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen) { /* - * If FD_CLOEXEC is available, rb_fork_internal waits the child's execve. - * So setpgid is done in the child when rb_fork_internal is returned in + * If FD_CLOEXEC is available, rb_fork_async_signal_safe waits the child's execve. + * So setpgid is done in the child when rb_fork_async_signal_safe is returned in * the parent. * No race condition, even without setpgid from the parent. * (Is there an environment which has setpgid but no FD_CLOEXEC?) @@ -3154,21 +3154,6 @@ pipe_nocrash(int filedes[2], VALUE fds) return ret; } -struct chfunc_protect_t { - int (*chfunc)(void*, char *, size_t); - void *arg; - char *errmsg; - size_t buflen; -}; - -static VALUE -chfunc_protect(VALUE arg) -{ - struct chfunc_protect_t *p = (struct chfunc_protect_t *)arg; - - return (VALUE)(*p->chfunc)(p->arg, p->errmsg, p->buflen); -} - #ifndef O_BINARY #define O_BINARY 0 #endif @@ -3345,9 +3330,8 @@ recv_child_error(int fd, int *statep, VALUE *excp, int *errp, char *errmsg, size return size != 0; } -static rb_pid_t -rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg, - int chfunc_is_async_signal_safe, VALUE fds, +rb_pid_t +rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen) { rb_pid_t pid; @@ -3355,75 +3339,59 @@ rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg, int ep[2]; VALUE exc = Qnil; int error_occurred; + int chfunc_is_async_signal_safe = TRUE; if (status) *status = 0; - if (!chfunc) { - pid = retry_fork(status, NULL, FALSE); - if (pid < 0) - return pid; - if (!pid) { - forked_child = 1; - after_fork(); - } + if (pipe_nocrash(ep, fds)) return -1; + pid = retry_fork(status, ep, chfunc_is_async_signal_safe); + if (pid < 0) return pid; - } - else { - if (pipe_nocrash(ep, fds)) return -1; - pid = retry_fork(status, ep, chfunc_is_async_signal_safe); - if (pid < 0) - return pid; - if (!pid) { - int ret; - forked_child = 1; - close(ep[0]); - if (chfunc_is_async_signal_safe) - ret = chfunc(charg, errmsg, errmsg_buflen); - else { - struct chfunc_protect_t arg; - arg.chfunc = chfunc; - arg.arg = charg; - arg.errmsg = errmsg; - arg.buflen = errmsg_buflen; - ret = (int)rb_protect(chfunc_protect, (VALUE)&arg, &state); - } - if (!ret) _exit(EXIT_SUCCESS); - send_child_error(ep[1], state, errmsg, errmsg_buflen, chfunc_is_async_signal_safe); + if (!pid) { + int ret; + forked_child = 1; + close(ep[0]); + ret = chfunc(charg, errmsg, errmsg_buflen); + if (!ret) _exit(EXIT_SUCCESS); + send_child_error(ep[1], state, errmsg, errmsg_buflen, chfunc_is_async_signal_safe); #if EXIT_SUCCESS == 127 - _exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); #else - _exit(127); + _exit(127); #endif + } + close(ep[1]); + error_occurred = recv_child_error(ep[0], &state, &exc, &err, errmsg, errmsg_buflen, chfunc_is_async_signal_safe); + if (state || error_occurred) { + if (status) { + rb_protect(proc_syswait, (VALUE)pid, status); + if (state) *status = state; } - close(ep[1]); - error_occurred = recv_child_error(ep[0], &state, &exc, &err, errmsg, errmsg_buflen, chfunc_is_async_signal_safe); - if (state || error_occurred) { - if (status) { - rb_protect(proc_syswait, (VALUE)pid, status); - if (state) *status = state; - } - else { - rb_syswait(pid); - if (state) rb_exc_raise(exc); - } - errno = err; - return -1; + else { + rb_syswait(pid); + if (state) rb_exc_raise(exc); } - return pid; + errno = err; + return -1; } -} - -rb_pid_t -rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, - char *errmsg, size_t errmsg_buflen) -{ - return rb_fork_internal(status, chfunc, charg, TRUE, fds, errmsg, errmsg_buflen); + return pid; } rb_pid_t rb_fork_ruby(int *status) { - return rb_fork_internal(status, NULL, NULL, FALSE, Qnil, NULL, 0); + rb_pid_t pid; + + if (status) *status = 0; + + pid = retry_fork(status, NULL, FALSE); + if (pid < 0) + return pid; + if (!pid) { + forked_child = 1; + after_fork(); + } + return pid; } #endif -- cgit v1.2.3