mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
windows: workaround kernel race condition
This was causing flaky CI failures.
This commit is contained in:
parent
c17e18647b
commit
b2bc6073c8
@ -1912,6 +1912,7 @@ pub const CreateProcessError = error{
|
|||||||
NameTooLong,
|
NameTooLong,
|
||||||
InvalidExe,
|
InvalidExe,
|
||||||
SystemResources,
|
SystemResources,
|
||||||
|
FileBusy,
|
||||||
Unexpected,
|
Unexpected,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1982,6 +1983,7 @@ pub fn CreateProcessW(
|
|||||||
.INVALID_PARAMETER => unreachable,
|
.INVALID_PARAMETER => unreachable,
|
||||||
.INVALID_NAME => return error.InvalidName,
|
.INVALID_NAME => return error.InvalidName,
|
||||||
.FILENAME_EXCED_RANGE => return error.NameTooLong,
|
.FILENAME_EXCED_RANGE => return error.NameTooLong,
|
||||||
|
.SHARING_VIOLATION => return error.FileBusy,
|
||||||
// These are all the system errors that are mapped to ENOEXEC by
|
// These are all the system errors that are mapped to ENOEXEC by
|
||||||
// the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error
|
// the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error
|
||||||
// (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK)
|
// (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK)
|
||||||
|
|||||||
14
src/link.zig
14
src/link.zig
@ -616,9 +616,19 @@ pub const File = struct {
|
|||||||
&coff.mf
|
&coff.mf
|
||||||
else
|
else
|
||||||
unreachable;
|
unreachable;
|
||||||
mf.file = try base.emit.root_dir.handle.openFile(base.emit.sub_path, .{
|
mf.file = for (0..2) |_| break base.emit.root_dir.handle.openFile(base.emit.sub_path, .{
|
||||||
.mode = .read_write,
|
.mode = .read_write,
|
||||||
});
|
}) catch |err| switch (err) {
|
||||||
|
error.AccessDenied => switch (builtin.os.tag) {
|
||||||
|
.windows => {
|
||||||
|
// give the kernel a chance to finish closing the executable handle
|
||||||
|
std.os.windows.kernel32.Sleep(0);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => return error.AccessDenied,
|
||||||
|
},
|
||||||
|
else => |e| return e,
|
||||||
|
} else return error.AccessDenied;
|
||||||
base.file = mf.file;
|
base.file = mf.file;
|
||||||
try mf.ensureTotalCapacity(@intCast(mf.nodes.items[0].location().resolve(mf)[1]));
|
try mf.ensureTotalCapacity(@intCast(mf.nodes.items[0].location().resolve(mf)[1]));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -71,7 +71,14 @@ pub fn main() anyerror!void {
|
|||||||
try testExec(allocator, "heLLo", "hello from exe\n");
|
try testExec(allocator, "heLLo", "hello from exe\n");
|
||||||
|
|
||||||
// now rename the exe to not have an extension
|
// now rename the exe to not have an extension
|
||||||
try tmp.dir.rename("hello.exe", "hello");
|
for (0..2) |_| break tmp.dir.rename("hello.exe", "hello") catch |err| switch (err) {
|
||||||
|
error.AccessDenied => {
|
||||||
|
// give the kernel a chance to finish closing the executable handle
|
||||||
|
std.os.windows.kernel32.Sleep(0);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => |e| return e,
|
||||||
|
} else return error.AccessDenied;
|
||||||
|
|
||||||
// with extension should now fail
|
// with extension should now fail
|
||||||
try testExecError(error.FileNotFound, allocator, "hello.exe");
|
try testExecError(error.FileNotFound, allocator, "hello.exe");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user