From 4ea2f441df36cec61e1017f4d795d4037326c98c Mon Sep 17 00:00:00 2001 From: Andrius Bentkus Date: Sat, 16 Jul 2022 15:46:13 +0300 Subject: Module: retry ZIR cache file creation There are no dir components, so you would think that this was unreachable, however we have observed on macOS two processes racing to do openat() with O_CREAT manifest in ENOENT. closes #12138 --- src/Module.zig | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Module.zig b/src/Module.zig index f3f1aa44e2..8c52176edd 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3569,20 +3569,25 @@ pub fn astGenFile(mod: *Module, file: *File) !void { // If another process is already working on this file, we will get the cached // version. Likewise if we're working on AstGen and another process asks for // the cached file, they'll get it. - const cache_file = zir_dir.createFile(&digest, .{ - .read = true, - .truncate = false, - .lock = lock, - }) catch |err| switch (err) { - error.NotDir => unreachable, // no dir components - error.InvalidUtf8 => unreachable, // it's a hex encoded name - error.BadPathName => unreachable, // it's a hex encoded name - error.NameTooLong => unreachable, // it's a fixed size name - error.PipeBusy => unreachable, // it's not a pipe - error.WouldBlock => unreachable, // not asking for non-blocking I/O - error.FileNotFound => unreachable, // no dir components - - else => |e| return e, // Retryable errors are handled at callsite. + const cache_file = while (true) { + break zir_dir.createFile(&digest, .{ + .read = true, + .truncate = false, + .lock = lock, + }) catch |err| switch (err) { + error.NotDir => unreachable, // no dir components + error.InvalidUtf8 => unreachable, // it's a hex encoded name + error.BadPathName => unreachable, // it's a hex encoded name + error.NameTooLong => unreachable, // it's a fixed size name + error.PipeBusy => unreachable, // it's not a pipe + error.WouldBlock => unreachable, // not asking for non-blocking I/O + // There are no dir components, so you would think that this was + // unreachable, however we have observed on macOS two processes racing + // to do openat() with O_CREAT manifest in ENOENT. + error.FileNotFound => continue, + + else => |e| return e, // Retryable errors are handled at callsite. + }; }; defer cache_file.close(); -- cgit v1.2.3