Skip to content

Commit 958faa7

Browse files
committed
windows: workaround kernel race condition the most
1 parent ea694bf commit 958faa7

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

src/link.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -616,19 +616,22 @@ pub const File = struct {
616616
&coff.mf
617617
else
618618
unreachable;
619-
mf.file = for (0..10) |_| break base.emit.root_dir.handle.openFile(base.emit.sub_path, .{
619+
var attempt: u5 = 0;
620+
mf.file = while (true) break base.emit.root_dir.handle.openFile(base.emit.sub_path, .{
620621
.mode = .read_write,
621622
}) catch |err| switch (err) {
622623
error.AccessDenied => switch (builtin.os.tag) {
623624
.windows => {
625+
if (attempt == 13) return error.AccessDenied;
624626
// give the kernel a chance to finish closing the executable handle
625-
std.os.windows.kernel32.Sleep(10);
627+
std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1);
628+
attempt += 1;
626629
continue;
627630
},
628631
else => return error.AccessDenied,
629632
},
630633
else => |e| return e,
631-
} else return error.AccessDenied;
634+
};
632635
base.file = mf.file;
633636
try mf.ensureTotalCapacity(@intCast(mf.nodes.items[0].location().resolve(mf)[1]));
634637
},

test/standalone/windows_spawn/main.zig

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,19 @@ pub fn main() anyerror!void {
7171
try testExec(allocator, "heLLo", "hello from exe\n");
7272

7373
// now rename the exe to not have an extension
74-
for (0..10) |_| break tmp.dir.rename("hello.exe", "hello") catch |err| switch (err) {
75-
error.AccessDenied => {
76-
// give the kernel a chance to finish closing the executable handle
77-
std.os.windows.kernel32.Sleep(10);
78-
continue;
79-
},
80-
else => |e| return e,
81-
} else return error.AccessDenied;
74+
{
75+
var attempt: u5 = 0;
76+
while (true) break tmp.dir.rename("hello.exe", "hello") catch |err| switch (err) {
77+
error.AccessDenied => {
78+
if (attempt == 13) return error.AccessDenied;
79+
// give the kernel a chance to finish closing the executable handle
80+
std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1);
81+
attempt += 1;
82+
continue;
83+
},
84+
else => |e| return e,
85+
};
86+
}
8287

8388
// with extension should now fail
8489
try testExecError(error.FileNotFound, allocator, "hello.exe");

0 commit comments

Comments
 (0)