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-27 15:32:34-08:00
log693b2ffd5cc5b17aedb58aed6b12237659a9dcb7
tree497e116206f1e7ee139294cf286a907bc916db3f
parentde3a2c0ebb60901f7603af0fbfa0a57b27a4b5a5

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
......@@ -2759,12 +2759,7 @@ fn dirCreateDirPathOpenWasi(
27592759
27602760fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat {
27612761 const t: *Threaded = @ptrCast(@alignCast(userdata));
2762 const file: File = if (is_windows) .{
2763 .handle = dir.handle,
2764 .flags = .{ .nonblocking = false },
2765 } else .{
2766 .handle = dir.handle,
2767 };
2762 const file: File = .{ .handle = dir.handle };
27682763 return fileStat(t, file);
27692764}
27702765
......@@ -3686,10 +3681,7 @@ fn dirCreateFileWindows(
36863681 errdefer windows.CloseHandle(handle);
36873682
36883683 const exclusive = switch (flags.lock) {
3689 .none => return .{
3690 .handle = handle,
3691 .flags = .{ .nonblocking = false },
3692 },
3684 .none => return .{ .handle = handle },
36933685 .shared => false,
36943686 .exclusive => true,
36953687 };
......@@ -3709,10 +3701,7 @@ fn dirCreateFileWindows(
37093701 )) {
37103702 .SUCCESS => {
37113703 syscall.finish();
3712 return .{
3713 .handle = handle,
3714 .flags = .{ .nonblocking = false },
3715 };
3704 return .{ .handle = handle };
37163705 },
37173706 .INSUFFICIENT_RESOURCES => return syscall.fail(error.SystemResources),
37183707 .LOCK_NOT_GRANTED => return syscall.fail(error.WouldBlock),
......@@ -4287,10 +4276,7 @@ pub fn dirOpenFileWtf16(
42874276 errdefer w.CloseHandle(handle);
42884277
42894278 const exclusive = switch (flags.lock) {
4290 .none => return .{
4291 .handle = handle,
4292 .flags = .{ .nonblocking = false },
4293 },
4279 .none => return .{ .handle = handle },
42944280 .shared => false,
42954281 .exclusive => true,
42964282 };
......@@ -4313,10 +4299,7 @@ pub fn dirOpenFileWtf16(
43134299 .ACCESS_VIOLATION => |err| return syscall.ntstatusBug(err), // bad io_status_block pointer
43144300 else => |status| return syscall.unexpectedNtstatus(status),
43154301 };
4316 return .{
4317 .handle = handle,
4318 .flags = .{ .nonblocking = false },
4319 };
4302 return .{ .handle = handle };
43204303}
43214304
43224305fn dirOpenFileWasi(
......@@ -8271,7 +8254,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
82718254 try syscall.checkCancel();
82728255 continue;
82738256 },
8274 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // wrong value for flags.nonblocking
8257 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // streaming read of async mode file
82758258 else => |status| return syscall.unexpectedNtstatus(status),
82768259 }
82778260 }
......@@ -14363,9 +14346,9 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro
1436314346 return .{
1436414347 .id = piProcInfo.hProcess,
1436514348 .thread_handle = piProcInfo.hThread,
14366 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14367 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14368 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,
14349 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h } else null,
14350 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h } else null,
14351 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h } else null,
1436914352 .request_resource_usage_statistics = options.request_resource_usage_statistics,
1437014353 };
1437114354}
......@@ -15499,7 +15482,6 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File {
1549915482 .pointer => @ptrFromInt(int),
1550015483 else => return error.UnsupportedOperation,
1550115484 },
15502 .flags = if (is_windows) .{ .nonblocking = true } else .{},
1550315485 };
1550415486}
1550515487
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;