mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.Build.Step.Compile: fix race condition in args file creation
Fixes #23993 Previously, if multiple build processes tried to create the same args file, there was a race condition with the use of the non-atomic `writeFile` function which could cause a spawned compiler to read an empty or incomplete args file. This commit avoids the race condition by first writing to a temporary file with a random path and renaming it to the desired path.
This commit is contained in:
parent
d57b1e3552
commit
d4df65e355
1 changed files with 20 additions and 1 deletions
|
|
@ -1827,7 +1827,26 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
|
||||||
_ = try std.fmt.bufPrint(&args_hex_hash, "{x}", .{&args_hash});
|
_ = try std.fmt.bufPrint(&args_hex_hash, "{x}", .{&args_hash});
|
||||||
|
|
||||||
const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;
|
const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;
|
||||||
try b.cache_root.handle.writeFile(.{ .sub_path = args_file, .data = args });
|
if (b.cache_root.handle.access(args_file, .{})) |_| {
|
||||||
|
// The args file is already present from a previous run.
|
||||||
|
} else |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
try b.cache_root.handle.makePath("tmp");
|
||||||
|
const rand_int = std.crypto.random.int(u64);
|
||||||
|
const tmp_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int);
|
||||||
|
try b.cache_root.handle.writeFile(.{ .sub_path = tmp_path, .data = args });
|
||||||
|
defer b.cache_root.handle.deleteFile(tmp_path) catch {
|
||||||
|
// It's fine if the temporary file can't be cleaned up.
|
||||||
|
};
|
||||||
|
b.cache_root.handle.rename(tmp_path, args_file) catch |rename_err| switch (rename_err) {
|
||||||
|
error.PathAlreadyExists => {
|
||||||
|
// The args file was created by another concurrent build process.
|
||||||
|
},
|
||||||
|
else => |other_err| return other_err,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => |other_err| return other_err,
|
||||||
|
}
|
||||||
|
|
||||||
const resolved_args_file = try mem.concat(arena, u8, &.{
|
const resolved_args_file = try mem.concat(arena, u8, &.{
|
||||||
"@",
|
"@",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue