aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-12-29 11:47:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-12-29 11:47:29 -0700
commit0b46c27333960553226abd4cc7aed10e07a14b06 (patch)
tree5c5a32a55b3b3ab89f2bdf3c5c719fbd043a3a08 /src
parente54fd2578195ce7857d921ac22b800d376fb870b (diff)
downloadzig-0b46c27333960553226abd4cc7aed10e07a14b06.tar.gz
zig-0b46c27333960553226abd4cc7aed10e07a14b06.zip
zig test: release Compilation Cache locks
before executing child process. This fixes a deadlock when the test wanted to obtain the same lock on compiler_rt.o that was held by the process building the test binary itself.
Diffstat (limited to 'src')
-rw-r--r--src/main.zig15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/main.zig b/src/main.zig
index 3bf9934d85..247f8327f0 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1769,7 +1769,8 @@ fn buildOutputType(
}) catch |err| {
fatal("unable to create compilation: {}", .{@errorName(err)});
};
- defer comp.destroy();
+ var comp_destroyed = false;
+ defer if (!comp_destroyed) comp.destroy();
if (show_builtin) {
return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
@@ -1845,9 +1846,10 @@ fn buildOutputType(
if (runtime_args_start) |i| {
try argv.appendSlice(all_args[i..]);
}
- // We do not execve for tests because if the test fails we want to print the error message and
- // invocation below.
+ // We do not execve for tests because if the test fails we want to print
+ // the error message and invocation below.
if (std.process.can_execv and arg_mode == .run and !watch) {
+ // execv releases the locks; no need to destroy the Compilation here.
const err = std.process.execv(gpa, argv.items);
const cmd = try argvCmd(arena, argv.items);
fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
@@ -1859,6 +1861,13 @@ fn buildOutputType(
child.stdout_behavior = .Inherit;
child.stderr_behavior = .Inherit;
+ if (!watch) {
+ // Here we release all the locks associated with the Compilation so
+ // that whatever this child process wants to do won't deadlock.
+ comp.destroy();
+ comp_destroyed = true;
+ }
+
const term = try child.spawnAndWait();
switch (arg_mode) {
.run => {