authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-21 19:08:52-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 12:10:00-08:00
log4f948bb13e1af263f544c86ac662bba298ca461f
tree7a3a3d0fa59b498876a510b9b353575e1b39ed2c
parent59ebd82ebf4746e47b3e84367b1ea87bbec7d222

std: back out the flags field of Io.File

For now, let us refrain from putting the sync mode into the Io.File struct, and document that to do concurrent batch operations, any Windows file handles must be in asynchronous mode. The consequences for violating this requirement is neither illegal behavior, nor an error, but that concurrency is lost. In other words, deadlock might occur. This prevents the addition of flags field. partial revert of 2faf14200f58ee72ec3a13e894d765f59e6483a9

3 files changed, 9 insertions(+), 43 deletions(-)

lib/std/Io/File.zig-15
......@@ -10,20 +10,8 @@ const assert = std.debug.assert;
1010const Dir = std.Io.Dir;
1111
1212handle: Handle,
13flags: Flags = .{},
1413
1514pub const Handle = std.posix.fd_t;
16pub const Flags = switch (native_os) {
17 .windows => packed struct(u1) {
18 /// * true: opened with MODE.IO.ASYNCHRONOUS
19 /// * false: opened with SYNCHRONOUS_ALERT or SYNCHRONOUS_NONALERT, or
20 /// not a file.
21 /// This is default-initialized to false as a workaround for
22 /// https://codeberg.org/ziglang/zig/issues/30842
23 nonblocking: bool = false,
24 },
25 else => packed struct(u0) {},
26};
2715
2816pub const Reader = @import("File/Reader.zig");
2917pub const Writer = @import("File/Writer.zig");
......@@ -89,7 +77,6 @@ pub fn stdout() File {
8977 return switch (native_os) {
9078 .windows => .{
9179 .handle = std.os.windows.peb().ProcessParameters.hStdOutput,
92 .flags = .{ .nonblocking = false },
9380 },
9481 else => .{
9582 .handle = std.posix.STDOUT_FILENO,
......@@ -101,7 +88,6 @@ pub fn stderr() File {
10188 return switch (native_os) {
10289 .windows => .{
10390 .handle = std.os.windows.peb().ProcessParameters.hStdError,
104 .flags = .{ .nonblocking = false },
10591 },
10692 else => .{
10793 .handle = std.posix.STDERR_FILENO,
......@@ -113,7 +99,6 @@ pub fn stdin() File {
11399 return switch (native_os) {
114100 .windows => .{
115101 .handle = std.os.windows.peb().ProcessParameters.hStdInput,
116 .flags = .{ .nonblocking = false },
117102 },
118103 else => .{
119104 .handle = std.posix.STDIN_FILENO,
lib/std/Io/Threaded.zig+9-27
......@@ -2764,12 +2764,7 @@ fn dirCreateDirPathOpenWasi(
27642764
27652765fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat {
27662766 const t: *Threaded = @ptrCast(@alignCast(userdata));
2767 const file: File = if (is_windows) .{
2768 .handle = dir.handle,
2769 .flags = .{ .nonblocking = false },
2770 } else .{
2771 .handle = dir.handle,
2772 };
2767 const file: File = .{ .handle = dir.handle };
27732768 return fileStat(t, file);
27742769}
27752770
......@@ -3692,10 +3687,7 @@ fn dirCreateFileWindows(
36923687 errdefer windows.CloseHandle(handle);
36933688
36943689 const exclusive = switch (flags.lock) {
3695 .none => return .{
3696 .handle = handle,
3697 .flags = .{ .nonblocking = false },
3698 },
3690 .none => return .{ .handle = handle },
36993691 .shared => false,
37003692 .exclusive => true,
37013693 };
......@@ -3715,10 +3707,7 @@ fn dirCreateFileWindows(
37153707 )) {
37163708 .SUCCESS => {
37173709 syscall.finish();
3718 return .{
3719 .handle = handle,
3720 .flags = .{ .nonblocking = false },
3721 };
3710 return .{ .handle = handle };
37223711 },
37233712 .INSUFFICIENT_RESOURCES => return syscall.fail(error.SystemResources),
37243713 .LOCK_NOT_GRANTED => return syscall.fail(error.WouldBlock),
......@@ -4289,10 +4278,7 @@ pub fn dirOpenFileWtf16(
42894278 errdefer w.CloseHandle(handle);
42904279
42914280 const exclusive = switch (flags.lock) {
4292 .none => return .{
4293 .handle = handle,
4294 .flags = .{ .nonblocking = false },
4295 },
4281 .none => return .{ .handle = handle },
42964282 .shared => false,
42974283 .exclusive => true,
42984284 };
......@@ -4315,10 +4301,7 @@ pub fn dirOpenFileWtf16(
43154301 .ACCESS_VIOLATION => |err| return syscall.ntstatusBug(err), // bad io_status_block pointer
43164302 else => |status| return syscall.unexpectedNtstatus(status),
43174303 };
4318 return .{
4319 .handle = handle,
4320 .flags = .{ .nonblocking = false },
4321 };
4304 return .{ .handle = handle };
43224305}
43234306
43244307fn dirOpenFileWasi(
......@@ -8414,7 +8397,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
84148397 try syscall.checkCancel();
84158398 continue;
84168399 },
8417 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // wrong value for flags.nonblocking
8400 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // streaming read of async mode file
84188401 else => |status| return syscall.unexpectedNtstatus(status),
84198402 }
84208403 }
......@@ -14602,9 +14585,9 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro
1460214585 return .{
1460314586 .id = piProcInfo.hProcess,
1460414587 .thread_handle = piProcInfo.hThread,
14605 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14606 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14607 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14588 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h } else null,
14589 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h } else null,
14590 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h } else null,
1460814591 .request_resource_usage_statistics = options.request_resource_usage_statistics,
1460914592 };
1461014593}
......@@ -15738,7 +15721,6 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File {
1573815721 .pointer => @ptrFromInt(int),
1573915722 else => return error.UnsupportedOperation,
1574015723 },
15741 .flags = if (is_windows) .{ .nonblocking = true } else .{},
1574215724 };
1574315725}
1574415726
lib/std/Progress.zig-1
......@@ -979,7 +979,6 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
979979 if (main_parent == .unused) continue;
980980 const file: Io.File = .{
981981 .handle = main_storage.getIpcFd() orelse continue,
982 .flags = if (is_windows) .{ .nonblocking = true } else .{},
983982 };
984983 const opt_saved_metadata = findOld(file.handle, old_ipc_metadata_fds, old_ipc_metadata);
985984 var bytes_read: usize = 0;