From patchwork Sun May 6 16:24:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10382893 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 22D7C60236 for ; Sun, 6 May 2018 16:25:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0297F28A94 for ; Sun, 6 May 2018 16:25:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EA1D728B52; Sun, 6 May 2018 16:25:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6295228A94 for ; Sun, 6 May 2018 16:25:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751736AbeEFQY7 (ORCPT ); Sun, 6 May 2018 12:24:59 -0400 Received: from orcrist.hmeau.com ([104.223.48.154]:36466 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751711AbeEFQY7 (ORCPT ); Sun, 6 May 2018 12:24:59 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1fFMSy-0008Io-ME; Mon, 07 May 2018 00:24:52 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1fFMSw-00079N-28; Mon, 07 May 2018 00:24:50 +0800 Date: Mon, 7 May 2018 00:24:50 +0800 From: Herbert Xu To: Jilles Tjoelker Cc: Leah Neukirchen , dash@vger.kernel.org Subject: [PATCH v2] jobs - Do not block when waiting on SIGCHLD Message-ID: <20180506162449.u6ld2meqmmxwdmgc@gondor.apana.org.au> References: <87wowjsfcw.fsf@gmail.com> <20180505160243.t5rujv3eifiust5a@gondor.apana.org.au> <20180506135343.GB39956@stack.nl> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180506135343.GB39956@stack.nl> User-Agent: NeoMutt/20170113 (1.7.2) Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Sun, May 06, 2018 at 03:53:43PM +0200, Jilles Tjoelker wrote: > > Now each of the first four executable lines of waitforjob() does > something different for jp == NULL and jp != NULL. It probably makes > more sense to separate the jp == NULL case into a new function. Thanks, that's a good point. However, because it's convenient to call waitforjob with NULL in eval, I'll keep it in the same function but create two distinct code paths for it. However, a bigger issue is that the original fix was incomplete. In particular, multiple jobs may have exited when gotsigchld is set. But the loop will exit after just waiting for one job if no new jobs exit triggering a new SIGCHLD. ---8<--- Because of the nature of SIGCHLD, the process may have already been waited on and therefore we must be prepared for the case that wait may block. So ensure that it doesn't by using WNOHANG. Furthermore, multiple jobs may have exited when gotsigchld is set. Therefore we need to wait until there are no zombies left. Fixes: 03876c0743a5 ("eval: Reap zombies after built-in...") Signed-off-by: Herbert Xu diff --git a/src/jobs.c b/src/jobs.c index 1a97c54..606d603 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -975,10 +975,17 @@ waitforjob(struct job *jp) int st; TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0)); - while ((jp && jp->state == JOBRUNNING) || gotsigchld) - dowait(DOWAIT_BLOCK, jp); - if (!jp) + if (!jp) { + int pid = gotsigchld; + + while (pid > 0) + pid = dowait(DOWAIT_NORMAL, NULL); + return exitstatus; + } + + while (jp->state == JOBRUNNING) + dowait(DOWAIT_BLOCK, jp); st = getstatus(jp); #if JOBS if (jp->jobctl) {