1 /* POSIX-based operating system interface for GNU Make.
2 Copyright (C) 2016 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/>. */
24 #if defined(HAVE_PSELECT) && defined(HAVE_SYS_SELECT_H)
25 # include <sys/select.h>
34 /* This section provides OS-specific functions to support the jobserver. */
36 /* These track the state of the jobserver pipe. Passed to child instances. */
37 static int job_fds[2] = { -1, -1 };
39 /* Used to signal read() that a SIGCHLD happened. Always CLOEXEC.
40 If we use pselect() this will never be created and always -1.
42 static int job_rfd = -1;
44 /* Token written to the pipe (could be any character...) */
45 static char token = '+';
51 /* Pretend we succeeded. */
54 EINTRLOOP (job_rfd, dup (job_fds[0]));
56 CLOSE_ON_EXEC (job_rfd);
63 jobserver_setup (int slots)
67 EINTRLOOP (r, pipe (job_fds));
69 pfatal_with_name (_("creating jobs pipe"));
71 if (make_job_rfd () < 0)
72 pfatal_with_name (_("duping jobs pipe"));
76 EINTRLOOP (r, write (job_fds[1], &token, 1));
78 pfatal_with_name (_("init jobserver pipe"));
85 jobserver_parse_auth (const char *auth)
87 /* Given the command-line parameter, parse it. */
88 if (sscanf (auth, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
90 _("internal error: invalid --jobserver-auth string '%s'"), auth);
93 (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
96 # define FD_OK(_f) (fcntl ((_f), F_GETFD) != -1)
101 /* Make sure our pipeline is valid, and (possibly) create a duplicate pipe,
102 that will be closed in the SIGCHLD handler. If this fails with EBADF,
103 the parent has closed the pipe on us because it didn't think we were a
104 submake. If so, warn and default to -j1. */
106 if (!FD_OK (job_fds[0]) || !FD_OK (job_fds[1]) || make_job_rfd () < 0)
109 pfatal_with_name (_("jobserver pipeline"));
111 job_fds[0] = job_fds[1] = -1;
120 jobserver_get_auth (void)
122 char *auth = xmalloc ((INTSTR_LENGTH * 2) + 2);
123 sprintf (auth, "%d,%d", job_fds[0], job_fds[1]);
128 jobserver_enabled (void)
130 return job_fds[0] >= 0;
134 jobserver_clear (void)
143 job_fds[0] = job_fds[1] = job_rfd = -1;
147 jobserver_release (int is_fatal)
150 EINTRLOOP (r, write (job_fds[1], &token, 1));
154 pfatal_with_name (_("write jobserver"));
155 perror_with_name ("write", "");
160 jobserver_acquire_all (void)
162 unsigned int tokens = 0;
164 /* Close the write side, so the read() won't hang. */
172 EINTRLOOP (r, read (job_fds[0], &intake, 1));
179 /* Prepare the jobserver to start a child process. */
181 jobserver_pre_child (int recursive)
183 /* If it's not a recursive make, avoid polutting the jobserver pipes. */
184 if (!recursive && job_fds[0] >= 0)
186 CLOSE_ON_EXEC (job_fds[0]);
187 CLOSE_ON_EXEC (job_fds[1]);
192 jobserver_post_child (int recursive)
194 #if defined(F_GETFD) && defined(F_SETFD)
195 if (!recursive && job_fds[0] >= 0)
198 for (i = 0; i < 2; ++i)
201 EINTRLOOP (flags, fcntl (job_fds[i], F_GETFD));
205 EINTRLOOP (r, fcntl (job_fds[i], F_SETFD, flags & ~FD_CLOEXEC));
213 jobserver_signal (void)
223 jobserver_pre_acquire (void)
225 /* Make sure we have a dup'd FD. */
226 if (job_rfd < 0 && job_fds[0] >= 0 && make_job_rfd () < 0)
227 pfatal_with_name (_("duping jobs pipe"));
232 /* Use pselect() to atomically wait for both a signal and a file descriptor.
233 It also provides a timeout facility so we don't need to use SIGALRM.
235 This method relies on the fact that SIGCHLD will be blocked everywhere,
236 and only unblocked (atomically) within the pselect() call, so we can
237 never miss a SIGCHLD.
240 jobserver_acquire (int timeout)
244 struct timespec spec;
245 struct timespec *specp = NULL;
249 sigemptyset (&empty);
252 FD_SET (job_fds[0], &readfds);
256 /* Alarm after one second (is this too granular?) */
262 r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty);
266 /* Better be SIGCHLD. */
268 pfatal_with_name (_("pselect jobs pipe"));
276 /* The read FD is ready: read it! */
277 EINTRLOOP (r, read (job_fds[0], &intake, 1));
279 pfatal_with_name (_("read jobs pipe"));
281 /* What does it mean if read() returns 0? It shouldn't happen because only
282 the master make can reap all the tokens and close the write side...?? */
288 /* This method uses a "traditional" UNIX model for waiting on both a signal
289 and a file descriptor. However, it's complex and since we have a SIGCHLD
290 handler installed we need to check ALL system calls for EINTR: painful!
292 Read a token. As long as there's no token available we'll block. We
293 enable interruptible system calls before the read(2) so that if we get a
294 SIGCHLD while we're waiting, we'll return with EINTR and we can process the
295 death(s) and return tokens to the free pool.
297 Once we return from the read, we immediately reinstate restartable system
298 calls. This allows us to not worry about checking for EINTR on all the
299 other system calls in the program.
301 There is one other twist: there is a span between the time reap_children()
302 does its last check for dead children and the time the read(2) call is
303 entered, below, where if a child dies we won't notice. This is extremely
304 serious as it could cause us to deadlock, given the right set of events.
306 To avoid this, we do the following: before we reap_children(), we dup(2)
307 the read FD on the jobserver pipe. The read(2) call below uses that new
308 FD. In the signal handler, we close that FD. That way, if a child dies
309 during the section mentioned above, the read(2) will be invoked with an
310 invalid FD and will return immediately with EBADF. */
313 job_noop (int sig UNUSED)
317 /* Set the child handler action flags to FLAGS. */
319 set_child_handler_action_flags (int set_handler, int set_alarm)
324 /* The child handler must be turned off here. */
325 signal (SIGCHLD, SIG_DFL);
328 memset (&sa, '\0', sizeof sa);
329 sa.sa_handler = child_handler;
330 sa.sa_flags = set_handler ? 0 : SA_RESTART;
333 if (sigaction (SIGCHLD, &sa, NULL) < 0)
334 pfatal_with_name ("sigaction: SIGCHLD");
337 #if defined SIGCLD && SIGCLD != SIGCHLD
338 if (sigaction (SIGCLD, &sa, NULL) < 0)
339 pfatal_with_name ("sigaction: SIGCLD");
345 /* If we're about to enter the read(), set an alarm to wake up in a
346 second so we can check if the load has dropped and we can start more
347 work. On the way out, turn off the alarm and set SIG_DFL. */
350 sa.sa_handler = job_noop;
352 if (sigaction (SIGALRM, &sa, NULL) < 0)
353 pfatal_with_name ("sigaction: SIGALRM");
359 sa.sa_handler = SIG_DFL;
361 if (sigaction (SIGALRM, &sa, NULL) < 0)
362 pfatal_with_name ("sigaction: SIGALRM");
369 jobserver_acquire (int timeout)
375 /* Set interruptible system calls, and read() for a job token. */
376 set_child_handler_action_flags (1, timeout);
378 EINTRLOOP (got_token, read (job_rfd, &intake, 1));
381 set_child_handler_action_flags (0, timeout);
386 /* If the error _wasn't_ expected (EINTR or EBADF), fatal. Otherwise,
387 go back and reap_children(), and try again. */
390 if (errno != EINTR && errno != EBADF)
391 pfatal_with_name (_("read jobs pipe"));
394 DB (DB_JOBS, ("Read returned EBADF.\n"));
401 #endif /* MAKE_JOBSERVER */
403 /* Create a "bad" file descriptor for stdin when parallel jobs are run. */
407 static int bad_stdin = -1;
409 /* Set up a bad standard input that reads from a broken pipe. */
413 /* Make a file descriptor that is the read end of a broken pipe.
414 This will be used for some children's standard inputs. */
418 /* Close the write side. */
419 (void) close (pd[1]);
420 /* Save the read side. */
423 /* Set the descriptor to close on exec, so it does not litter any
424 child's descriptor table. When it is dup2'd onto descriptor 0,
425 that descriptor will not close on exec. */
426 CLOSE_ON_EXEC (bad_stdin);