1 /* POSIX-based operating system interface for GNU Make.
2 Copyright (C) 2016-2020 Free Software Foundation, Inc.
3 This file is part of GNU Make.
5 GNU Make is free software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3 of the License, or (at your option) any later
10 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along with
15 this program. If not, see <http://www.gnu.org/licenses/>. */
23 #elif defined(HAVE_SYS_FILE_H)
24 # include <sys/file.h>
27 #if defined(HAVE_PSELECT) && defined(HAVE_SYS_SELECT_H)
28 # include <sys/select.h>
37 /* This section provides OS-specific functions to support the jobserver. */
39 /* These track the state of the jobserver pipe. Passed to child instances. */
40 static int job_fds[2] = { -1, -1 };
42 /* Used to signal read() that a SIGCHLD happened. Always CLOEXEC.
43 If we use pselect() this will never be created and always -1.
45 static int job_rfd = -1;
47 /* Token written to the pipe (could be any character...) */
48 static char token = '+';
54 /* Pretend we succeeded. */
57 EINTRLOOP (job_rfd, dup (job_fds[0]));
59 fd_noinherit (job_rfd);
66 set_blocking (int fd, int blocking)
68 /* If we're not using pselect() don't change the blocking. */
71 EINTRLOOP (flags, fcntl (fd, F_GETFL));
75 flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
76 EINTRLOOP (r, fcntl (fd, F_SETFL, flags));
78 pfatal_with_name ("fcntl(O_NONBLOCK)");
84 jobserver_setup (int slots)
88 EINTRLOOP (r, pipe (job_fds));
90 pfatal_with_name (_("creating jobs pipe"));
92 /* By default we don't send the job pipe FDs to our children.
93 See jobserver_pre_child() and jobserver_post_child(). */
94 fd_noinherit (job_fds[0]);
95 fd_noinherit (job_fds[1]);
97 if (make_job_rfd () < 0)
98 pfatal_with_name (_("duping jobs pipe"));
102 EINTRLOOP (r, write (job_fds[1], &token, 1));
104 pfatal_with_name (_("init jobserver pipe"));
107 /* When using pselect() we want the read to be non-blocking. */
108 set_blocking (job_fds[0], 0);
114 jobserver_parse_auth (const char *auth)
116 /* Given the command-line parameter, parse it. */
117 if (sscanf (auth, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
119 _("internal error: invalid --jobserver-auth string '%s'"), auth);
122 (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
125 # define FD_OK(_f) (fcntl ((_f), F_GETFD) != -1)
130 /* Make sure our pipeline is valid, and (possibly) create a duplicate pipe,
131 that will be closed in the SIGCHLD handler. If this fails with EBADF,
132 the parent has closed the pipe on us because it didn't think we were a
133 submake. If so, warn and default to -j1. */
135 if (!FD_OK (job_fds[0]) || !FD_OK (job_fds[1]) || make_job_rfd () < 0)
138 pfatal_with_name (_("jobserver pipeline"));
140 job_fds[0] = job_fds[1] = -1;
145 /* When using pselect() we want the read to be non-blocking. */
146 set_blocking (job_fds[0], 0);
152 jobserver_get_auth (void)
154 char *auth = xmalloc ((INTSTR_LENGTH * 2) + 2);
155 sprintf (auth, "%d,%d", job_fds[0], job_fds[1]);
160 jobserver_enabled (void)
162 return job_fds[0] >= 0;
166 jobserver_clear (void)
175 job_fds[0] = job_fds[1] = job_rfd = -1;
179 jobserver_release (int is_fatal)
182 EINTRLOOP (r, write (job_fds[1], &token, 1));
186 pfatal_with_name (_("write jobserver"));
187 perror_with_name ("write", "");
192 jobserver_acquire_all (void)
194 unsigned int tokens = 0;
196 /* Use blocking reads to wait for all outstanding jobs. */
197 set_blocking (job_fds[0], 1);
199 /* Close the write side, so the read() won't hang forever. */
207 EINTRLOOP (r, read (job_fds[0], &intake, 1));
214 /* Prepare the jobserver to start a child process. */
216 jobserver_pre_child (int recursive)
218 if (recursive && job_fds[0] >= 0)
220 fd_inherit (job_fds[0]);
221 fd_inherit (job_fds[1]);
225 /* Reconfigure the jobserver after starting a child process. */
227 jobserver_post_child (int recursive)
229 if (recursive && job_fds[0] >= 0)
231 fd_noinherit (job_fds[0]);
232 fd_noinherit (job_fds[1]);
237 jobserver_signal (void)
247 jobserver_pre_acquire (void)
249 /* Make sure we have a dup'd FD. */
250 if (job_rfd < 0 && job_fds[0] >= 0 && make_job_rfd () < 0)
251 pfatal_with_name (_("duping jobs pipe"));
256 /* Use pselect() to atomically wait for both a signal and a file descriptor.
257 It also provides a timeout facility so we don't need to use SIGALRM.
259 This method relies on the fact that SIGCHLD will be blocked everywhere,
260 and only unblocked (atomically) within the pselect() call, so we can
261 never miss a SIGCHLD.
264 jobserver_acquire (int timeout)
266 struct timespec spec;
267 struct timespec *specp = NULL;
270 sigemptyset (&empty);
274 /* Alarm after one second (is this too granular?) */
287 FD_SET (job_fds[0], &readfds);
289 r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty);
294 /* SIGCHLD will show up as an EINTR. */
298 /* Someone closed the jobs pipe.
299 That shouldn't happen but if it does we're done. */
300 O (fatal, NILF, _("job server shut down"));
303 pfatal_with_name (_("pselect jobs pipe"));
310 /* The read FD is ready: read it! This is non-blocking. */
311 EINTRLOOP (r, read (job_fds[0], &intake, 1));
315 /* Someone sniped our token! Try again. */
319 pfatal_with_name (_("read jobs pipe"));
322 /* read() should never return 0: only the master make can reap all the
323 tokens and close the write side...?? */
330 /* This method uses a "traditional" UNIX model for waiting on both a signal
331 and a file descriptor. However, it's complex and since we have a SIGCHLD
332 handler installed we need to check ALL system calls for EINTR: painful!
334 Read a token. As long as there's no token available we'll block. We
335 enable interruptible system calls before the read(2) so that if we get a
336 SIGCHLD while we're waiting, we'll return with EINTR and we can process the
337 death(s) and return tokens to the free pool.
339 Once we return from the read, we immediately reinstate restartable system
340 calls. This allows us to not worry about checking for EINTR on all the
341 other system calls in the program.
343 There is one other twist: there is a span between the time reap_children()
344 does its last check for dead children and the time the read(2) call is
345 entered, below, where if a child dies we won't notice. This is extremely
346 serious as it could cause us to deadlock, given the right set of events.
348 To avoid this, we do the following: before we reap_children(), we dup(2)
349 the read FD on the jobserver pipe. The read(2) call below uses that new
350 FD. In the signal handler, we close that FD. That way, if a child dies
351 during the section mentioned above, the read(2) will be invoked with an
352 invalid FD and will return immediately with EBADF. */
355 job_noop (int sig UNUSED)
359 /* Set the child handler action flags to FLAGS. */
361 set_child_handler_action_flags (int set_handler, int set_alarm)
366 /* The child handler must be turned off here. */
367 signal (SIGCHLD, SIG_DFL);
370 memset (&sa, '\0', sizeof sa);
371 sa.sa_handler = child_handler;
372 sa.sa_flags = set_handler ? 0 : SA_RESTART;
375 if (sigaction (SIGCHLD, &sa, NULL) < 0)
376 pfatal_with_name ("sigaction: SIGCHLD");
379 #if defined SIGCLD && SIGCLD != SIGCHLD
380 if (sigaction (SIGCLD, &sa, NULL) < 0)
381 pfatal_with_name ("sigaction: SIGCLD");
387 /* If we're about to enter the read(), set an alarm to wake up in a
388 second so we can check if the load has dropped and we can start more
389 work. On the way out, turn off the alarm and set SIG_DFL. */
392 sa.sa_handler = job_noop;
394 if (sigaction (SIGALRM, &sa, NULL) < 0)
395 pfatal_with_name ("sigaction: SIGALRM");
401 sa.sa_handler = SIG_DFL;
403 if (sigaction (SIGALRM, &sa, NULL) < 0)
404 pfatal_with_name ("sigaction: SIGALRM");
411 jobserver_acquire (int timeout)
417 /* Set interruptible system calls, and read() for a job token. */
418 set_child_handler_action_flags (1, timeout);
420 EINTRLOOP (got_token, read (job_rfd, &intake, 1));
423 set_child_handler_action_flags (0, timeout);
428 /* If the error _wasn't_ expected (EINTR or EBADF), fatal. Otherwise,
429 go back and reap_children(), and try again. */
432 if (errno != EINTR && errno != EBADF)
433 pfatal_with_name (_("read jobs pipe"));
436 DB (DB_JOBS, ("Read returned EBADF.\n"));
441 #endif /* HAVE_PSELECT */
443 #endif /* MAKE_JOBSERVER */
445 /* Create a "bad" file descriptor for stdin when parallel jobs are run. */
449 static int bad_stdin = -1;
451 /* Set up a bad standard input that reads from a broken pipe. */
455 /* Make a file descriptor that is the read end of a broken pipe.
456 This will be used for some children's standard inputs. */
460 /* Close the write side. */
461 (void) close (pd[1]);
462 /* Save the read side. */
465 /* Set the descriptor to close on exec, so it does not litter any
466 child's descriptor table. When it is dup2'd onto descriptor 0,
467 that descriptor will not close on exec. */
468 fd_noinherit (bad_stdin);
475 /* Set file descriptors to be inherited / not inherited by subprocesses. */
477 #if !defined(F_SETFD) || !defined(F_GETFD)
478 void fd_inherit (int fd) {}
479 void fd_noinherit (int fd) {}
484 # define FD_CLOEXEC 1
491 EINTRLOOP (flags, fcntl (fd, F_GETFD));
495 flags &= ~FD_CLOEXEC;
496 EINTRLOOP (r, fcntl (fd, F_SETFD, flags));
501 fd_noinherit (int fd)
504 EINTRLOOP(flags, fcntl(fd, F_GETFD));
509 EINTRLOOP(r, fcntl(fd, F_SETFD, flags));