There is no need to resize the pollfd array, it can only ever have 2+maxJobs
entries, so allocate at startup. Use an 'int jobPipe[2]' within the job structure, and create pipes directly into it. Common up the code that creates all the pipes - making them all non-block on the read side in the process. Call Job_CatchChildren() directly from Job_CatchOutput() so that it only gets called when a child actually exits. NB: Something causes a 'pregnant pause' if (for example) you call 'nbmake obj' in src/tools. Introduced between netbsd 3 and 4.
This commit is contained in:
parent
e160c7cdec
commit
505a3bb2b7
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.c,v 1.121 2006/10/09 20:44:35 apb Exp $ */
|
||||
/* $NetBSD: job.c,v 1.122 2006/10/11 07:01:44 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.121 2006/10/09 20:44:35 apb Exp $";
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.122 2006/10/11 07:01:44 dsl Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: job.c,v 1.121 2006/10/09 20:44:35 apb Exp $");
|
||||
__RCSID("$NetBSD: job.c,v 1.122 2006/10/11 07:01:44 dsl Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -197,9 +197,6 @@ static int numCommands; /* The number of commands actually printed
|
||||
#define JOB_RUNNING 0 /* Job is running */
|
||||
#define JOB_ERROR 1 /* Error in starting the job */
|
||||
#define JOB_FINISHED 2 /* The job is already finished */
|
||||
#define JOB_STOPPED 3 /* The job is stopped */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Descriptions for various shells.
|
||||
@ -299,12 +296,9 @@ static int make_suspended = 0; /* non-zero if we've seen a SIGTSTP (etc) */
|
||||
static struct pollfd *fds = NULL;
|
||||
static Job **jobfds = NULL;
|
||||
static int nfds = 0;
|
||||
static int maxfds = 0;
|
||||
static void watchfd(Job *);
|
||||
static void clearfd(Job *);
|
||||
static int readyfd(Job *);
|
||||
#define JBSTART 256
|
||||
#define JBFACTOR 2
|
||||
|
||||
STATIC GNode *lastNode; /* The node for which output was most recently
|
||||
* produced. */
|
||||
@ -312,10 +306,8 @@ STATIC const char *targFmt; /* Format string to use to head output from a
|
||||
* job when it's not the most-recent job heard
|
||||
* from */
|
||||
static Job tokenWaitJob; /* token wait pseudo-job */
|
||||
int job_pipe[2] = { -1, -1 }; /* job server pipes. */
|
||||
|
||||
static Job childExitJob; /* child exit pseudo-job */
|
||||
int exit_pipe[2] = { -1, -1 }; /* child exit signal pipe. */
|
||||
#define CHILD_EXIT "."
|
||||
#define DO_JOB_RESUME "R"
|
||||
|
||||
@ -382,6 +374,37 @@ static void JobSigUnlock(sigset_t *omaskp)
|
||||
(void)sigprocmask(SIG_SETMASK, omaskp, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
JobCreatePipe(Job *job, int minfd)
|
||||
{
|
||||
int i, fd;
|
||||
|
||||
if (pipe(job->jobPipe) == -1)
|
||||
Punt("Cannot create pipe: %s", strerror(errno));
|
||||
|
||||
/* Set close-on-exec flag for both */
|
||||
(void)fcntl(job->jobPipe[0], F_SETFD, 1);
|
||||
(void)fcntl(job->jobPipe[1], F_SETFD, 1);
|
||||
|
||||
/*
|
||||
* We mark the input side of the pipe non-blocking; we poll(2) the
|
||||
* pipe when we're waiting for a job token, but we might lose the
|
||||
* race for the token when a new one becomes available, so the read
|
||||
* from the pipe should not block.
|
||||
*/
|
||||
fcntl(job->jobPipe[0], F_SETFL,
|
||||
fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Avoid using low numbered fds */
|
||||
fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
|
||||
if (fd != -1) {
|
||||
close(job->jobPipe[i]);
|
||||
job->jobPipe[i] = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* JobCondPassSig --
|
||||
@ -438,7 +461,7 @@ JobCondPassSig(int signo)
|
||||
static void
|
||||
JobChildSig(int signo __unused)
|
||||
{
|
||||
write(exit_pipe[1], CHILD_EXIT, 1);
|
||||
write(childExitJob.outPipe, CHILD_EXIT, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -465,7 +488,7 @@ JobContinueSig(int signo __unused)
|
||||
* Defer sending to SIGCONT to our stopped children until we return
|
||||
* from the signal handler.
|
||||
*/
|
||||
write(exit_pipe[1], DO_JOB_RESUME, 1);
|
||||
write(childExitJob.outPipe, DO_JOB_RESUME, 1);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -880,10 +903,9 @@ static void
|
||||
JobClose(Job *job)
|
||||
{
|
||||
clearfd(job);
|
||||
if (job->outPipe != job->inPipe) {
|
||||
(void)close(job->outPipe);
|
||||
job->outPipe = -1;
|
||||
}
|
||||
(void)close(job->outPipe);
|
||||
job->outPipe = -1;
|
||||
|
||||
JobDoOutput(job, TRUE);
|
||||
(void)close(job->inPipe);
|
||||
job->inPipe = -1;
|
||||
@ -1291,8 +1313,8 @@ JobExec(Job *job, char **argv)
|
||||
/*
|
||||
* Pass job token pipe to submakes.
|
||||
*/
|
||||
fcntl(job_pipe[0], F_SETFD, 0);
|
||||
fcntl(job_pipe[1], F_SETFD, 0);
|
||||
fcntl(tokenWaitJob.inPipe, F_SETFD, 0);
|
||||
fcntl(tokenWaitJob.outPipe, F_SETFD, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1437,6 +1459,7 @@ JobMakeArgv(Job *job, char **argv)
|
||||
*
|
||||
* NB: I'm fairly sure that this code is never called with JOB_SPECIAL set
|
||||
* JOB_IGNDOTS is never set (dsl)
|
||||
* Also the return value is ignored by everyone.
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
@ -1453,7 +1476,8 @@ JobStart(GNode *gn, int flags)
|
||||
break;
|
||||
}
|
||||
if (job >= job_table_end)
|
||||
Punt("JobStart out of memory");
|
||||
Punt("JobStart no job slots vacant");
|
||||
|
||||
memset(job, 0, sizeof *job);
|
||||
job->job_state = JOB_ST_SETUP;
|
||||
if (gn->type & OP_SPECIAL)
|
||||
@ -1490,7 +1514,7 @@ JobStart(GNode *gn, int flags)
|
||||
* we just set the file to be stdout. Cute, huh?
|
||||
*/
|
||||
if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) ||
|
||||
(!noExecute && !touchFlag)) {
|
||||
(!noExecute && !touchFlag)) {
|
||||
/*
|
||||
* tfile is the name of a file into which all shell commands are
|
||||
* put. It is used over by removing it before the child shell is
|
||||
@ -1614,18 +1638,8 @@ JobStart(GNode *gn, int flags)
|
||||
*/
|
||||
JobMakeArgv(job, argv);
|
||||
|
||||
/*
|
||||
* If we're using pipes to catch output, create the pipe by which we'll
|
||||
* get the shell's output. If we're using files, print out that we're
|
||||
* starting a job and then set up its temporary-file name.
|
||||
*/
|
||||
int fd[2];
|
||||
if (pipe(fd) == -1)
|
||||
Punt("Cannot create pipe: %s", strerror(errno));
|
||||
job->inPipe = fd[0];
|
||||
job->outPipe = fd[1];
|
||||
(void)fcntl(job->inPipe, F_SETFD, 1);
|
||||
(void)fcntl(job->outPipe, F_SETFD, 1);
|
||||
/* Create the pipe by which we'll get the shell's output. */
|
||||
JobCreatePipe(job, 3);
|
||||
|
||||
JobExec(job, argv);
|
||||
return(JOB_RUNNING);
|
||||
@ -1726,6 +1740,8 @@ end_loop:
|
||||
nRead = read(job->inPipe, &job->outBuf[job->curPos],
|
||||
JOB_BUFSIZE - job->curPos);
|
||||
if (nRead < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return;
|
||||
if (DEBUG(JOB)) {
|
||||
perror("JobDoOutput(piperead)");
|
||||
}
|
||||
@ -1850,7 +1866,6 @@ JobRun(GNode *targ)
|
||||
JobStart(targ, JOB_SPECIAL);
|
||||
while (jobTokensRunning) {
|
||||
Job_CatchOutput();
|
||||
Job_CatchChildren();
|
||||
}
|
||||
#else
|
||||
Compat_Make(targ, targ);
|
||||
@ -1959,32 +1974,38 @@ Job_CatchChildren(void)
|
||||
void
|
||||
Job_CatchOutput(void)
|
||||
{
|
||||
int nready;
|
||||
Job *job;
|
||||
int nready;
|
||||
Job *job;
|
||||
int i;
|
||||
|
||||
(void)fflush(stdout);
|
||||
|
||||
/* The first fd in the list is the job token pipe */
|
||||
nready = poll(fds + 1 - wantToken, nfds + 1 - wantToken, POLL_MSEC);
|
||||
if (nready <= 0)
|
||||
return;
|
||||
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
|
||||
|
||||
if (readyfd(&childExitJob)) {
|
||||
if (nready < 0 || readyfd(&childExitJob)) {
|
||||
char token = 0;
|
||||
nready -= 1;
|
||||
(void)read(childExitJob.inPipe, &token, 1);
|
||||
if (token == DO_JOB_RESUME[0])
|
||||
/* Complete relay requested from our SIGCONT handler */
|
||||
JobRestartJobs();
|
||||
Job_CatchChildren();
|
||||
}
|
||||
|
||||
for (job = job_table; nready && job < job_table_end; job++) {
|
||||
if (nready <= 0)
|
||||
return;
|
||||
|
||||
if (wantToken && readyfd(&tokenWaitJob))
|
||||
nready--;
|
||||
|
||||
for (i = 2; i < nfds; i++) {
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
job = jobfds[i];
|
||||
if (job->job_state != JOB_ST_RUNNING)
|
||||
continue;
|
||||
if (readyfd(job)) {
|
||||
JobDoOutput(job, FALSE);
|
||||
nready -= 1;
|
||||
}
|
||||
JobDoOutput(job, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2100,12 +2121,15 @@ Job_Init(void)
|
||||
|
||||
Shell_Init();
|
||||
|
||||
if (pipe(exit_pipe) < 0)
|
||||
Fatal("error in pipe: %s", strerror(errno));
|
||||
fcntl(exit_pipe[0], F_SETFD, 1);
|
||||
fcntl(exit_pipe[1], F_SETFD, 1);
|
||||
JobCreatePipe(&childExitJob, 3);
|
||||
|
||||
childExitJob.inPipe = exit_pipe[0];
|
||||
/* We can only need to wait for tokens, children and output from each job */
|
||||
fds = emalloc(sizeof (*fds) * (2 + maxJobs));
|
||||
jobfds = emalloc(sizeof (*jobfds) * (2 + maxJobs));
|
||||
|
||||
/* These are permanent entries and take slots 0 and 1 */
|
||||
watchfd(&tokenWaitJob);
|
||||
watchfd(&childExitJob);
|
||||
|
||||
sigemptyset(&caught_signals);
|
||||
/*
|
||||
@ -2522,7 +2546,6 @@ Job_Wait(void)
|
||||
aborting = ABORT_WAIT;
|
||||
while (jobTokensRunning != 0) {
|
||||
Job_CatchOutput();
|
||||
Job_CatchChildren();
|
||||
}
|
||||
aborting = 0;
|
||||
}
|
||||
@ -2617,32 +2640,8 @@ JobRestartJobs(void)
|
||||
static void
|
||||
watchfd(Job *job)
|
||||
{
|
||||
int i;
|
||||
if (job->inPollfd != NULL)
|
||||
Punt("Watching watched job");
|
||||
if (fds == NULL) {
|
||||
maxfds = JBSTART;
|
||||
fds = emalloc(sizeof(struct pollfd) * maxfds);
|
||||
jobfds = emalloc(sizeof(Job **) * maxfds);
|
||||
|
||||
fds[0].fd = job_pipe[0];
|
||||
fds[0].events = POLLIN;
|
||||
jobfds[0] = &tokenWaitJob;
|
||||
tokenWaitJob.inPollfd = &fds[0];
|
||||
nfds++;
|
||||
|
||||
fds[1].fd = exit_pipe[0];
|
||||
fds[1].events = POLLIN;
|
||||
jobfds[1] = &childExitJob;
|
||||
childExitJob.inPollfd = &fds[1];
|
||||
nfds++;
|
||||
} else if (nfds == maxfds) {
|
||||
maxfds *= JBFACTOR;
|
||||
fds = erealloc(fds, sizeof(struct pollfd) * maxfds);
|
||||
jobfds = erealloc(jobfds, sizeof(Job **) * maxfds);
|
||||
for (i = 0; i < nfds; i++)
|
||||
jobfds[i]->inPollfd = &fds[i];
|
||||
}
|
||||
|
||||
fds[nfds].fd = job->inPipe;
|
||||
fds[nfds].events = POLLIN;
|
||||
@ -2696,13 +2695,13 @@ JobTokenAdd(void)
|
||||
char tok = JOB_TOKENS[aborting], tok1;
|
||||
|
||||
/* If we are depositing an error token flush everything else */
|
||||
while (tok != '+' && read(job_pipe[0], &tok1, 1) == 1)
|
||||
while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1)
|
||||
continue;
|
||||
|
||||
if (DEBUG(JOB))
|
||||
printf("(%d) aborting %d, deposit token %c\n",
|
||||
getpid(), aborting, JOB_TOKENS[aborting]);
|
||||
write(job_pipe[1], &tok, 1);
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -2714,54 +2713,35 @@ JobTokenAdd(void)
|
||||
*/
|
||||
|
||||
void
|
||||
Job_ServerStart(void)
|
||||
Job_ServerStart(int max_tokens, int jp_0, int jp_1)
|
||||
{
|
||||
int i, fd, flags;
|
||||
int i;
|
||||
char jobarg[64];
|
||||
|
||||
if (pipe(job_pipe) < 0)
|
||||
Fatal("error in pipe: %s", strerror(errno));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Avoid using low numbered fds */
|
||||
fd = fcntl(job_pipe[i], F_DUPFD, 15);
|
||||
if (fd != -1) {
|
||||
close(job_pipe[i]);
|
||||
job_pipe[i] = fd;
|
||||
}
|
||||
if (jp_0 >= 0 && jp_1 >= 0) {
|
||||
/* Pipe passed in from parent */
|
||||
tokenWaitJob.inPipe = jp_0;
|
||||
tokenWaitJob.outPipe = jp_1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We mark the input side of the pipe non-blocking; we poll(2) the
|
||||
* pipe when we're waiting for a job token, but we might lose the
|
||||
* race for the token when a new one becomes available, so the read
|
||||
* from the pipe should not block.
|
||||
*/
|
||||
flags = fcntl(job_pipe[0], F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(job_pipe[0], F_SETFL, flags);
|
||||
JobCreatePipe(&tokenWaitJob, 15);
|
||||
|
||||
/*
|
||||
* Mark job pipes as close-on-exec.
|
||||
* Note that we will clear this when executing submakes.
|
||||
*/
|
||||
fcntl(job_pipe[0], F_SETFD, 1);
|
||||
fcntl(job_pipe[1], F_SETFD, 1);
|
||||
|
||||
snprintf(jobarg, sizeof(jobarg), "%d,%d", job_pipe[0], job_pipe[1]);
|
||||
snprintf(jobarg, sizeof(jobarg), "%d,%d",
|
||||
tokenWaitJob.inPipe, tokenWaitJob.outPipe);
|
||||
|
||||
Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL);
|
||||
|
||||
/*
|
||||
* Preload job_pipe with one token per job, save the one
|
||||
* Preload the job pipe with one token per job, save the one
|
||||
* "extra" token for the primary job.
|
||||
*
|
||||
* XXX should clip maxJobs against PIPE_BUF -- if maxJobTokens is
|
||||
* XXX should clip maxJobs against PIPE_BUF -- if max_tokens is
|
||||
* larger than the write buffer size of the pipe, we will
|
||||
* deadlock here.
|
||||
*/
|
||||
for (i=1; i < maxJobTokens; i++)
|
||||
for (i = 1; i < max_tokens; i++)
|
||||
JobTokenAdd();
|
||||
}
|
||||
|
||||
@ -2814,7 +2794,7 @@ Job_TokenWithdraw(void)
|
||||
if (aborting || (jobTokensRunning >= maxJobs))
|
||||
return FALSE;
|
||||
|
||||
count = read(job_pipe[0], &tok, 1);
|
||||
count = read(tokenWaitJob.inPipe, &tok, 1);
|
||||
if (count == 0)
|
||||
Fatal("eof on job pipe!");
|
||||
if (count < 0 && jobTokensRunning != 0) {
|
||||
@ -2831,16 +2811,16 @@ Job_TokenWithdraw(void)
|
||||
/* make being abvorted - remove any other job tokens */
|
||||
if (DEBUG(JOB))
|
||||
printf("(%d) aborted by token %c\n", getpid(), tok);
|
||||
while (read(job_pipe[0], &tok1, 1) == 1)
|
||||
while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
|
||||
continue;
|
||||
/* And put the stopper back */
|
||||
write(job_pipe[1], &tok, 1);
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
Fatal("A failure has been detected in another branch of the parallel make");
|
||||
}
|
||||
|
||||
if (count == 1 && jobTokensRunning == 0)
|
||||
/* We didn't want the token really */
|
||||
write(job_pipe[1], &tok, 1);
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
|
||||
jobTokensRunning++;
|
||||
if (DEBUG(JOB))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.h,v 1.32 2006/10/09 14:36:41 dsl Exp $ */
|
||||
/* $NetBSD: job.h,v 1.33 2006/10/11 07:01:44 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -129,10 +129,6 @@ emul_poll(struct pollfd *fd, int nfd, int timeout);
|
||||
* 6) A word of flags which determine how the module handles errors,
|
||||
* echoing, etc. for the job
|
||||
*
|
||||
* The job "table" is kept as a linked Lst in 'jobs', with the number of
|
||||
* active jobs maintained in the 'nJobs' variable. At no time will this
|
||||
* exceed the value of 'maxJobs', initialized by the Job_Init function.
|
||||
*
|
||||
* When a job is finished, the Make_Update function is called on each of the
|
||||
* parents of the node which was just remade. This takes care of the upward
|
||||
* traversal of the dependency graph.
|
||||
@ -163,17 +159,17 @@ typedef struct Job {
|
||||
* commands */
|
||||
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
|
||||
|
||||
int inPipe; /* Input side of pipe associated
|
||||
* with job's output channel */
|
||||
int jobPipe[2]; /* Pipe for readind output from job */
|
||||
struct pollfd *inPollfd; /* pollfd associated with inPipe */
|
||||
int outPipe; /* Output side of pipe associated with
|
||||
* job's output channel */
|
||||
char outBuf[JOB_BUFSIZE + 1];
|
||||
/* Buffer for storing the output of the
|
||||
* job, line by line */
|
||||
int curPos; /* Current position in op_outBuf */
|
||||
} Job;
|
||||
|
||||
#define inPipe jobPipe[0]
|
||||
#define outPipe jobPipe[1]
|
||||
|
||||
|
||||
/*-
|
||||
* Shell Specifications:
|
||||
@ -239,10 +235,8 @@ typedef struct Shell {
|
||||
extern const char *shellPath;
|
||||
extern const char *shellName;
|
||||
|
||||
extern int job_pipe[2]; /* token pipe for jobs. */
|
||||
extern int jobTokensRunning; /* tokens currently "out" */
|
||||
extern int maxJobs; /* Max jobs we can run */
|
||||
extern int maxJobTokens; /* Number of token for the job pipe */
|
||||
|
||||
void Shell_Init(void);
|
||||
const char *Shell_GetNewline(void);
|
||||
@ -263,6 +257,6 @@ void Job_AbortAll(void);
|
||||
void JobFlagForMigration(int);
|
||||
void Job_TokenReturn(void);
|
||||
Boolean Job_TokenWithdraw(void);
|
||||
void Job_ServerStart(void);
|
||||
void Job_ServerStart(int, int, int);
|
||||
|
||||
#endif /* _JOB_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.131 2006/10/09 14:36:41 dsl Exp $ */
|
||||
/* $NetBSD: main.c,v 1.132 2006/10/11 07:01:44 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,7 +69,7 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.131 2006/10/09 14:36:41 dsl Exp $";
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.132 2006/10/11 07:01:44 dsl Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.131 2006/10/09 14:36:41 dsl Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.132 2006/10/11 07:01:44 dsl Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -156,7 +156,7 @@ static Lst makefiles; /* ordered list of makefiles to read */
|
||||
static Boolean printVars; /* print value of one or more vars */
|
||||
static Lst variables; /* list of variables to print */
|
||||
int maxJobs; /* -j argument */
|
||||
int maxJobTokens; /* -j argument */
|
||||
static int maxJobTokens; /* -j argument */
|
||||
Boolean compatMake; /* -B argument */
|
||||
int debug; /* -d argument */
|
||||
Boolean noExecute; /* -n flag */
|
||||
@ -170,6 +170,7 @@ Boolean oldVars; /* variable substitution style */
|
||||
Boolean checkEnvFirst; /* -e flag */
|
||||
Boolean parseWarnFatal; /* -W flag */
|
||||
Boolean jobServer; /* -J flag */
|
||||
static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
|
||||
Boolean varNoExportEnv; /* -X flag */
|
||||
static Boolean jobsRunning; /* TRUE if the jobs might be running */
|
||||
static const char * tracefile;
|
||||
@ -277,23 +278,22 @@ rearg:
|
||||
break;
|
||||
case 'J':
|
||||
if (argvalue == NULL) goto noarg;
|
||||
if (sscanf(argvalue, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
|
||||
/* backslash to avoid trigraph ??) */
|
||||
if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
|
||||
(void)fprintf(stderr,
|
||||
"%s: internal error -- J option malformed (%s?\?)\n",
|
||||
"%s: internal error -- J option malformed (%s)\n",
|
||||
progname, argvalue);
|
||||
usage();
|
||||
}
|
||||
if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
|
||||
(fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
|
||||
if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
|
||||
(fcntl(jp_1, F_GETFD, 0) < 0)) {
|
||||
#if 0
|
||||
(void)fprintf(stderr,
|
||||
"%s: ###### warning -- J descriptors were closed!\n",
|
||||
progname);
|
||||
exit(2);
|
||||
#endif
|
||||
job_pipe[0] = -1;
|
||||
job_pipe[1] = -1;
|
||||
jp_0 = -1;
|
||||
jp_1 = -1;
|
||||
compatMake = TRUE;
|
||||
} else {
|
||||
Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
|
||||
@ -933,11 +933,11 @@ main(int argc, char **argv)
|
||||
if (p1)
|
||||
free(p1);
|
||||
|
||||
if (!jobServer && !compatMake)
|
||||
Job_ServerStart();
|
||||
if (!compatMake)
|
||||
Job_ServerStart(maxJobTokens, jp_0, jp_1);
|
||||
if (DEBUG(JOB))
|
||||
printf("job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
|
||||
job_pipe[0], job_pipe[1], maxJobs, maxJobTokens, compatMake);
|
||||
jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
|
||||
|
||||
Main_ExportMAKEFLAGS(TRUE); /* initial export */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.c,v 1.64 2006/10/09 14:36:41 dsl Exp $ */
|
||||
/* $NetBSD: make.c,v 1.65 2006/10/11 07:01:44 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.64 2006/10/09 14:36:41 dsl Exp $";
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.65 2006/10/11 07:01:44 dsl Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: make.c,v 1.64 2006/10/09 14:36:41 dsl Exp $");
|
||||
__RCSID("$NetBSD: make.c,v 1.65 2006/10/11 07:01:44 dsl Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -1230,7 +1230,6 @@ Make_Run(Lst targs)
|
||||
*/
|
||||
while (!Lst_IsEmpty(toBeMade) || jobTokensRunning > 0) {
|
||||
Job_CatchOutput();
|
||||
Job_CatchChildren();
|
||||
(void)MakeStartJobs();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user