* Fixed error rebuilding makefiles with -j>1
authorPaul Smith <psmith@gnu.org>
Fri, 9 Jul 1999 22:55:44 +0000 (22:55 +0000)
committerPaul Smith <psmith@gnu.org>
Fri, 9 Jul 1999 22:55:44 +0000 (22:55 +0000)
* Fixed problem with job pipe and -j>1 when waiting on -l loads.

ChangeLog
dep.h
job.c
remake.c

index 5f93445..b88e034 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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;
 
index d39c558..94b70e1 100644 (file)
--- 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;