diff options
Diffstat (limited to 'source/d/make/b552b05251980f693c729e251f93f5225b400714.patch')
-rw-r--r-- | source/d/make/b552b05251980f693c729e251f93f5225b400714.patch | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/source/d/make/b552b05251980f693c729e251f93f5225b400714.patch b/source/d/make/b552b05251980f693c729e251f93f5225b400714.patch deleted file mode 100644 index 6f44ae3f2..000000000 --- a/source/d/make/b552b05251980f693c729e251f93f5225b400714.patch +++ /dev/null @@ -1,170 +0,0 @@ -From b552b05251980f693c729e251f93f5225b400714 Mon Sep 17 00:00:00 2001 -From: Paul Smith <psmith@gnu.org> -Date: Sat, 3 Jun 2017 16:20:51 -0400 -Subject: [SV 51159] Use a non-blocking read with pselect to avoid hangs. - -* posixos.c (set_blocking): Set blocking on a file descriptor. -(jobserver_setup): Set non-blocking on the jobserver read side. -(jobserver_parse_auth): Ditto. -(jobserver_acquire_all): Set blocking to avoid a busy-wait loop. -(jobserver_acquire): If the non-blocking read() returns without -taking a token then try again. ---- - posixos.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 71 insertions(+), 26 deletions(-) - -diff --git a/posixos.c b/posixos.c -index e642d7f..dbafa51 100644 ---- a/posixos.c -+++ b/posixos.c -@@ -62,6 +62,24 @@ make_job_rfd (void) - #endif - } - -+static void -+set_blocking (int fd, int blocking) -+{ -+ // If we're not using pselect() don't change the blocking -+#ifdef HAVE_PSELECT -+ int flags; -+ EINTRLOOP (flags, fcntl (fd, F_GETFL)); -+ if (flags >= 0) -+ { -+ int r; -+ flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); -+ EINTRLOOP (r, fcntl (fd, F_SETFL, flags)); -+ if (r < 0) -+ pfatal_with_name ("fcntl(O_NONBLOCK)"); -+ } -+#endif -+} -+ - unsigned int - jobserver_setup (int slots) - { -@@ -86,6 +104,9 @@ jobserver_setup (int slots) - pfatal_with_name (_("init jobserver pipe")); - } - -+ /* When using pselect() we want the read to be non-blocking. */ -+ set_blocking (job_fds[0], 0); -+ - return 1; - } - -@@ -121,6 +142,9 @@ jobserver_parse_auth (const char *auth) - return 0; - } - -+ /* When using pselect() we want the read to be non-blocking. */ -+ set_blocking (job_fds[0], 0); -+ - return 1; - } - -@@ -169,7 +193,10 @@ jobserver_acquire_all (void) - { - unsigned int tokens = 0; - -- /* Close the write side, so the read() won't hang. */ -+ /* Use blocking reads to wait for all outstanding jobs. */ -+ set_blocking (job_fds[0], 1); -+ -+ /* Close the write side, so the read() won't hang forever. */ - close (job_fds[1]); - job_fds[1] = -1; - -@@ -236,18 +263,12 @@ jobserver_pre_acquire (void) - unsigned int - jobserver_acquire (int timeout) - { -- sigset_t empty; -- fd_set readfds; - struct timespec spec; - struct timespec *specp = NULL; -- int r; -- char intake; -+ sigset_t empty; - - sigemptyset (&empty); - -- FD_ZERO (&readfds); -- FD_SET (job_fds[0], &readfds); -- - if (timeout) - { - /* Alarm after one second (is this too granular?) */ -@@ -256,28 +277,52 @@ jobserver_acquire (int timeout) - specp = &spec; - } - -- r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty); -- -- if (r == -1) -+ while (1) - { -- /* Better be SIGCHLD. */ -- if (errno != EINTR) -- pfatal_with_name (_("pselect jobs pipe")); -- return 0; -- } -+ fd_set readfds; -+ int r; -+ char intake; - -- if (r == 0) -- /* Timeout. */ -- return 0; -+ FD_ZERO (&readfds); -+ FD_SET (job_fds[0], &readfds); - -- /* The read FD is ready: read it! */ -- EINTRLOOP (r, read (job_fds[0], &intake, 1)); -- if (r < 0) -- pfatal_with_name (_("read jobs pipe")); -+ r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty); -+ if (r < 0) -+ switch (errno) -+ { -+ case EINTR: -+ /* SIGCHLD will show up as an EINTR. */ -+ return 0; -+ -+ case EBADF: -+ /* Someone closed the jobs pipe. -+ That shouldn't happen but if it does we're done. */ -+ O (fatal, NILF, _("job server shut down")); - -- /* What does it mean if read() returns 0? It shouldn't happen because only -- the master make can reap all the tokens and close the write side...?? */ -- return r > 0; -+ default: -+ pfatal_with_name (_("pselect jobs pipe")); -+ } -+ -+ if (r == 0) -+ /* Timeout. */ -+ return 0; -+ -+ /* The read FD is ready: read it! This is non-blocking. */ -+ EINTRLOOP (r, read (job_fds[0], &intake, 1)); -+ -+ if (r < 0) -+ { -+ /* Someone sniped our token! Try again. */ -+ if (errno == EAGAIN) -+ continue; -+ -+ pfatal_with_name (_("read jobs pipe")); -+ } -+ -+ /* read() should never return 0: only the master make can reap all the -+ tokens and close the write side...?? */ -+ return r > 0; -+ } - } - - #else --- -cgit v1.0-41-gc330 - |