authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-29 11:47:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-29 11:47:29-07:00
log0b46c27333960553226abd4cc7aed10e07a14b06
tree5c5a32a55b3b3ab89f2bdf3c5c719fbd043a3a08
parente54fd2578195ce7857d921ac22b800d376fb870b

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.

1 files changed, 12 insertions(+), 3 deletions(-)

src/main.zig+12-3
...@@ -1769,7 +1769,8 @@ fn buildOutputType(...@@ -1769,7 +1769,8 @@ fn buildOutputType(
1769 }) catch |err| {1769 }) catch |err| {
1770 fatal("unable to create compilation: {}", .{@errorName(err)});1770 fatal("unable to create compilation: {}", .{@errorName(err)});
1771 };1771 };
1772 defer comp.destroy();1772 var comp_destroyed = false;
1773 defer if (!comp_destroyed) comp.destroy();
17731774
1774 if (show_builtin) {1775 if (show_builtin) {
1775 return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));1776 return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
...@@ -1845,9 +1846,10 @@ fn buildOutputType(...@@ -1845,9 +1846,10 @@ fn buildOutputType(
1845 if (runtime_args_start) |i| {1846 if (runtime_args_start) |i| {
1846 try argv.appendSlice(all_args[i..]);1847 try argv.appendSlice(all_args[i..]);
1847 }1848 }
1848 // We do not execve for tests because if the test fails we want to print the error message and1849 // We do not execve for tests because if the test fails we want to print
1849 // invocation below.1850 // the error message and invocation below.
1850 if (std.process.can_execv and arg_mode == .run and !watch) {1851 if (std.process.can_execv and arg_mode == .run and !watch) {
1852 // execv releases the locks; no need to destroy the Compilation here.
1851 const err = std.process.execv(gpa, argv.items);1853 const err = std.process.execv(gpa, argv.items);
1852 const cmd = try argvCmd(arena, argv.items);1854 const cmd = try argvCmd(arena, argv.items);
1853 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });1855 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
...@@ -1859,6 +1861,13 @@ fn buildOutputType(...@@ -1859,6 +1861,13 @@ fn buildOutputType(
1859 child.stdout_behavior = .Inherit;1861 child.stdout_behavior = .Inherit;
1860 child.stderr_behavior = .Inherit;1862 child.stderr_behavior = .Inherit;
18611863
1864 if (!watch) {
1865 // Here we release all the locks associated with the Compilation so
1866 // that whatever this child process wants to do won't deadlock.
1867 comp.destroy();
1868 comp_destroyed = true;
1869 }
1870
1862 const term = try child.spawnAndWait();1871 const term = try child.spawnAndWait();
1863 switch (arg_mode) {1872 switch (arg_mode) {
1864 .run => {1873 .run => {