Messages in this thread | | | From | Linus Torvalds <> | Date | Mon, 11 May 2020 12:33:58 -0700 | Subject | Re: I disabled more compiler warnings.. |
| |
On Mon, May 11, 2020 at 10:59 AM Paul Smith <psmith@gnu.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
| |