[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=wi=SbaC20nRx5tmAZ2_tOpVOq7469V+KvZU9=4yvfvmnA@mail.gmail.com>
Date: Mon, 11 May 2020 12:33:58 -0700
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Paul Smith <psmith@....org>
Cc: David Laight <David.Laight@...lab.com>,
Arnd Bergmann <arnd@...db.de>,
Masahiro Yamada <yamada.masahiro@...ionext.com>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: I disabled more compiler warnings..
On Mon, May 11, 2020 at 10:59 AM Paul Smith <psmith@....org> wrote:
>
> As with all single-threaded applications, though, the problem is the
> difficulty (in a portable way) of handling both signals and wait*(2)
> reliably...
I do wonder if GNU make isn't making it worse for itself by blocking SIGCHLD.
I wonder if you could just have three different file descriptors:
- the "current token file descriptor"
- a /dev/null file descriptor
- the jobserver pipe file descriptor. This is left blocking.
and then make the rule be that
- the SIGCHLD handler just does
dup2(nullfd, jobserverfd);
This guarantees that any read() that was interrupted by a SIGCHLD
will now reliably return immediately. But it also guarantees that if
we raced, and the SIGCHLD happened just *before* we did the read(),
the read() will also exit immediately.
- the waiting code does
check_child_status();
for (;;) {
ret = read(jobserverfd, buffer, 1);
if (ret == 1) {
.. we got the token successfully, do whatever ..
return;
}
/* The read might fail because of SIGCHLD - either we got
interrupted, or the fd was replaced with /dev/null */
/* First, re-instate the pipe binding */
dup2(pipefd, jobserverfd);
/* Then do the child status stuff again */
check_child_status();
/* Ok, we can restart, there's no races with SIGCHLD */
}
which fundamentally doesn't have any races. Look, ma, no need for
nonblocking reads, or pselect().
I don't know. Maybe I missed something.
Linus
Powered by blists - more mailing lists