authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-29 16:51:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 19:49:08-07:00
log6b2709616e22e7651f16293034cc0d25f0e9be0a
treed3dc659be126b3e6212197c955c52fbe277894a9
parenta89d6878d2780f966b7327f8d366e6ac5f5cd8fc

frontend: ignore AccessDenied when writing builtin.zig

This issue already existed in master branch, however, the more aggressive caching of builtin.zig in this branch made it happen more often. I added doc comments to AtomicFile to explain when this problem can occur. For the compiler's use case, error.AccessDenied can be simply swallowed because it means the destination file already exists and there is nothing else to do besides proceed with the AtomicFile cleanup. I never solved the mystery of why the log statements weren't printing but those are temporary debugging instruments anyway, and I am already too many yaks deep to whip out another razor. closes #14978

2 files changed, 17 insertions(+), 17 deletions(-)

lib/std/fs/AtomicFile.zig+4
......@@ -65,6 +65,10 @@ pub fn deinit(self: *AtomicFile) void {
6565
6666pub const FinishError = posix.RenameError;
6767
68/// On Windows, this function introduces a period of time where some file
69/// system operations on the destination file will result in
70/// `error.AccessDenied`, including rename operations (such as the one used in
71/// this function).
6872pub fn finish(self: *AtomicFile) FinishError!void {
6973 assert(self.file_exists);
7074 if (self.file_open) {
src/Builtin.zig+13-17
......@@ -280,24 +280,19 @@ pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void {
280280
281281fn writeFile(file: *File, mod: *Module) !void {
282282 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
283 var af = mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf) catch |err| {
284 std.log.warn("unable to create builtin atomic file '{}{s}'", .{
285 mod.root, mod.root_src_path,
286 });
287 return err;
288 };
283 var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf);
289284 defer af.deinit();
290 af.file.writeAll(file.source) catch |err| {
291 std.log.warn("unable to write builtin file data to '{}{s}'", .{
292 mod.root, mod.root_src_path,
293 });
294 return err;
295 };
296 af.finish() catch |err| {
297 std.log.warn("unable to rename atomic builtin file into '{}{s}'", .{
298 mod.root, mod.root_src_path,
299 });
300 return err;
285 try af.file.writeAll(file.source);
286 af.finish() catch |err| switch (err) {
287 error.AccessDenied => switch (builtin.os.tag) {
288 .windows => {
289 // Very likely happened due to another process or thread
290 // simultaneously creating the same, correct builtin.zig file.
291 // This is not a problem; ignore it.
292 },
293 else => return err,
294 },
295 else => return err,
301296 };
302297
303298 file.stat = .{
......@@ -307,6 +302,7 @@ fn writeFile(file: *File, mod: *Module) !void {
307302 };
308303}
309304
305const builtin = @import("builtin");
310306const std = @import("std");
311307const Allocator = std.mem.Allocator;
312308const build_options = @import("build_options");