[SV 56918] Compute job slots properly on failing command

Ensure we properly reduce job_slots_used if a command fails because
it doesn't exist/can't be started.

* src/job.h (struct child): Add a field jobslot to be set when using
a job slot.
* src/job.c (start_waiting_job): Remember if we are using a job slot.
(reap_children): Reduce number of job slots used by jobslot.
This commit is contained in:
Paul Smith 2019-09-21 15:11:21 -04:00
parent e1c072aa7e
commit bd4ce86785
3 changed files with 21 additions and 8 deletions

View File

@ -1073,12 +1073,12 @@ reap_children (int block, int err)
{ {
DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"), DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"),
c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); c, pid2str (c->pid), c->remote ? _(" (remote)") : ""));
/* There is now another slot open. */
if (job_slots_used > 0)
--job_slots_used;
} }
/* There is now another slot open. */
if (job_slots_used > 0)
job_slots_used -= c->jobslot;
/* Remove the child from the chain and free it. */ /* Remove the child from the chain and free it. */
if (lastc == 0) if (lastc == 0)
children = c->next; children = c->next;
@ -1647,6 +1647,8 @@ start_waiting_job (struct child *c)
c->remote ? _(" (remote)") : "")); c->remote ? _(" (remote)") : ""));
/* One more job slot is in use. */ /* One more job slot is in use. */
++job_slots_used; ++job_slots_used;
assert (c->jobslot == 0);
c->jobslot = 1;
} }
children = c; children = c;
unblock_sigs (); unblock_sigs ();

View File

@ -61,6 +61,7 @@ struct child
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */ unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
unsigned int deleted:1; /* Nonzero if targets have been deleted. */ unsigned int deleted:1; /* Nonzero if targets have been deleted. */
unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */ unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */
unsigned int jobslot:1; /* Nonzero if it's reserved a job slot. */
unsigned int dontcare:1; /* Saved dontcare flag. */ unsigned int dontcare:1; /* Saved dontcare flag. */
}; };

View File

@ -42,21 +42,31 @@ my $err = $ERR_no_such_file;
run_make_test(qq! run_make_test(qq!
one: ; -$unk xx yy one: ; -$unk xx yy
two: ; $unk aa bb
!, !,
'one', "$unk xx yy\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;2: one] Error 127 (ignored)\n"); 'one', "$unk xx yy\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;2: one] Error 127 (ignored)\n");
# TEST #4 # TEST #4
# ------- # -------
run_make_test(undef, 'two -i', run_make_test(qq!
"$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;3: two] Error 127 (ignored)\n"); two: ; $unk aa bb
!, 'two -i',
"$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;2: two] Error 127 (ignored)\n");
# TEST #5 # TEST #5
# ------- # -------
run_make_test(undef, 'two', run_make_test(undef, 'two',
"$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: *** [#MAKEFILE#;3: two] Error 127\n", 512); "$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: *** [#MAKEFILE#;2: two] Error 127\n", 512);
# SV #56918 : Test the unknown command as the second recipe line
run_make_test(qq!
three:
\t\@echo one
\t$unk qq rr
!, 'three',
"one\n$unk qq rr\n#MAKE#: $unk: $err\n#MAKE#: *** [#MAKEFILE#;4: three] Error 127\n", 512);
# Try failing due to non-executable file # Try failing due to non-executable file