From bd4ce86785a1b12a76d3d4638f20d1e033dad1ec Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sat, 21 Sep 2019 15:11:21 -0400 Subject: [PATCH] [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. --- src/job.c | 10 ++++++---- src/job.h | 1 + tests/scripts/features/errors | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/job.c b/src/job.c index c7e7f795..ba3770ce 100644 --- a/src/job.c +++ b/src/job.c @@ -1073,12 +1073,12 @@ reap_children (int block, int err) { DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"), 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. */ if (lastc == 0) children = c->next; @@ -1647,6 +1647,8 @@ start_waiting_job (struct child *c) c->remote ? _(" (remote)") : "")); /* One more job slot is in use. */ ++job_slots_used; + assert (c->jobslot == 0); + c->jobslot = 1; } children = c; unblock_sigs (); diff --git a/src/job.h b/src/job.h index 4f1da97c..e20866a2 100644 --- a/src/job.h +++ b/src/job.h @@ -61,6 +61,7 @@ struct child 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 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. */ }; diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors index 1e155622..06b496a3 100644 --- a/tests/scripts/features/errors +++ b/tests/scripts/features/errors @@ -42,21 +42,31 @@ my $err = $ERR_no_such_file; run_make_test(qq! 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"); # TEST #4 # ------- -run_make_test(undef, 'two -i', - "$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;3: two] Error 127 (ignored)\n"); +run_make_test(qq! +two: ; $unk aa bb +!, 'two -i', + "$unk aa bb\n#MAKE#: $unk: $err\n#MAKE#: [#MAKEFILE#;2: two] Error 127 (ignored)\n"); # TEST #5 # ------- 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