summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--dep.h3
-rw-r--r--job.c5
-rw-r--r--remake.c15
4 files changed, 40 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 5f93445..b88e034 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+1999-07-09 Paul D. Smith <psmith@gnu.org>
+
+ * job.c (start_waiting_job): Don't get a second job token if we
+ already have one; if we're waiting on the load to go down
+ start_waiting_job() might get called twice on the same file.
+
+ * remake.c (update_goal_chain): If we try to update a goal and it
+ doesn't complete (e.g., parallel builds) remember that by setting
+ the `deferred' flag in the goal structure. Later when we're
+ determining the return value we consider a goal updated if either
+ the mtime has changed _or_ this flag was set. We need this
+ because the mtime doesn't change during the update_file() function
+ if we started a job running; instead it's set during the
+ reap_children() call. So, the code doesn't know it was updated
+ and returns a status of -1 (nothing done). This is OK during
+ "normal" builds since our caller (main) treats these cases
+ identically in that case, but if you're building makefiles the
+ difference is very important (whether we re-exec or not).
+
+ * dep.h: Add a `deferred' flag to track whether a goal was run but
+ not completed (parallel builds).
+
1999-07-08 Paul D. Smith <psmith@gnu.org>
* main.c (switches): Define a new switch -R (or
diff --git a/dep.h b/dep.h
index ca8112f..90999b6 100644
--- a/dep.h
+++ b/dep.h
@@ -38,7 +38,8 @@ struct dep
struct dep *next;
char *name;
struct file *file;
- int changed;
+ unsigned short changed;
+ unsigned short deferred; /* Only used in update_goal_chain(). */
};
diff --git a/job.c b/job.c
index 787678d..caabb1e 100644
--- a/job.c
+++ b/job.c
@@ -1133,8 +1133,9 @@ start_waiting_job (c)
{
#ifdef MAKE_JOBSERVER
/* If this is not a recurse command and we are controlling
- multiple jobs, obtain a token before starting child. */
- if (job_fds[0] >= 0 && !f->cmds->any_recurse)
+ multiple jobs, and we don't yet have one, obtain a token before
+ starting child. */
+ if (job_fds[0] >= 0 && !f->cmds->any_recurse && !c->job_token)
{
fd_set rfds;
diff --git a/remake.c b/remake.c
index d39c558..94b70e1 100644
--- a/remake.c
+++ b/remake.c
@@ -94,7 +94,7 @@ update_goal_chain (goals, makefiles)
struct dep *g;
for (g = goals; g != 0; g = g->next)
- g->changed = 0;
+ g->changed = g->deferred = 0;
}
#if 0
@@ -161,6 +161,16 @@ update_goal_chain (goals, makefiles)
decide when to give an "up to date" diagnostic. */
g->changed += commands_started - ocommands_started;
+ /* Set the goal's `deferred' flag if we started a command but
+ it didn't finish (parallel builds). We need to remember
+ this, because the next time through the goal chain the call
+ to reap_children() will set the mtime, not the call to
+ update_file() above. So, the saved mtime from before
+ update_file() will be the same as the mtime after it, and
+ we'll think nothing changed when it did (see below). */
+ if (file->command_state == cs_running)
+ g->deferred = 1;
+
stop = 0;
if (x != 0 || file->updated)
{
@@ -181,7 +191,7 @@ update_goal_chain (goals, makefiles)
stop = (!keep_going_flag && !question_flag
&& !makefiles);
}
- else if (MTIME (file) != mtime)
+ else if (MTIME (file) != mtime || g->deferred)
{
/* Updating was done. If this is a makefile and
just_print_flag or question_flag is set
@@ -189,6 +199,7 @@ update_goal_chain (goals, makefiles)
specified as a command-line target), don't
change STATUS. If STATUS is changed, we will
get re-exec'd, and fall into an infinite loop. */
+ g->deferred = 0;
if (!makefiles
|| (!just_print_flag && !question_flag))
status = 0;