From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.1 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 8B57E1F914 for ; Tue, 26 Jun 2018 09:38:20 +0000 (UTC) From: Eric Wong To: spew@80x24.org Subject: [PATCH 14/14] process.c (rb_waitpid): reimplement non-SIGCHLD code path Date: Tue, 26 Jun 2018 09:38:17 +0000 Message-Id: <20180626093817.1533-15-e@80x24.org> In-Reply-To: <20180626093817.1533-1-e@80x24.org> References: <20180626093817.1533-1-e@80x24.org> List-Id: This is only compile-tested, but should work the same way it did for platforms without SIGCHLD (I don't know which...) --- process.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/process.c b/process.c index 12a6d9b7b7..4f23bb5469 100644 --- a/process.c +++ b/process.c @@ -1085,23 +1085,51 @@ waitpid_wait(struct waitpid_state *w) } } +static void * +waitpid_blocking_no_SIGCHLD(void *x) +{ + struct waitpid_state *w = x; + + w->ret = do_waitpid(w->pid, &w->status, w->options); + + return 0; +} + +static void +waitpid_no_SIGCHLD(struct waitpid_state *w) +{ + if (w->options & WNOHANG) { + w->ret = do_waitpid(w->pid, &w->status, w->options); + } + else { + do { + rb_thread_call_without_gvl(waitpid_blocking_no_SIGCHLD, &w, + RUBY_UBF_PROCESS, 0); + } while (w->ret < 0 && errno == EINTR && (RUBY_VM_CHECK_INTS(w->ec),1)); + } +} + rb_pid_t rb_waitpid(rb_pid_t pid, int *st, int flags) { - rb_pid_t result; struct waitpid_state w; waitpid_state_init(&w, pid, flags); w.ec = GET_EC(); - waitpid_wait(&w); - if (st) *st = w.status; - result = w.ret; - if (result > 0) { - rb_last_status_set(*st, result); + if (RUBY_SIGCHLD) { + waitpid_wait(&w); + } + else { + waitpid_no_SIGCHLD(&w); + } + + if (st) *st = w.status; + if (w.ret > 0) { + rb_last_status_set(w.status, w.ret); } if (w.ret == -1) errno = w.errnum; - return result; + return w.ret; } -- EW