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;...@@ -10,20 +10,8 @@ const assert = std.debug.assert;
10const Dir = std.Io.Dir;10const Dir = std.Io.Dir;
1111
12handle: Handle,12handle: Handle,
13flags: Flags = .{},
1413
15pub const Handle = std.posix.fd_t;14pub 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
28pub const Reader = @import("File/Reader.zig");16pub const Reader = @import("File/Reader.zig");
29pub const Writer = @import("File/Writer.zig");17pub const Writer = @import("File/Writer.zig");
...@@ -89,7 +77,6 @@ pub fn stdout() File {...@@ -89,7 +77,6 @@ pub fn stdout() File {
89 return switch (native_os) {77 return switch (native_os) {
90 .windows => .{78 .windows => .{
91 .handle = std.os.windows.peb().ProcessParameters.hStdOutput,79 .handle = std.os.windows.peb().ProcessParameters.hStdOutput,
92 .flags = .{ .nonblocking = false },
93 },80 },
94 else => .{81 else => .{
95 .handle = std.posix.STDOUT_FILENO,82 .handle = std.posix.STDOUT_FILENO,
...@@ -101,7 +88,6 @@ pub fn stderr() File {...@@ -101,7 +88,6 @@ pub fn stderr() File {
101 return switch (native_os) {88 return switch (native_os) {
102 .windows => .{89 .windows => .{
103 .handle = std.os.windows.peb().ProcessParameters.hStdError,90 .handle = std.os.windows.peb().ProcessParameters.hStdError,
104 .flags = .{ .nonblocking = false },
105 },91 },
106 else => .{92 else => .{
107 .handle = std.posix.STDERR_FILENO,93 .handle = std.posix.STDERR_FILENO,
...@@ -113,7 +99,6 @@ pub fn stdin() File {...@@ -113,7 +99,6 @@ pub fn stdin() File {
113 return switch (native_os) {99 return switch (native_os) {
114 .windows => .{100 .windows => .{
115 .handle = std.os.windows.peb().ProcessParameters.hStdInput,101 .handle = std.os.windows.peb().ProcessParameters.hStdInput,
116 .flags = .{ .nonblocking = false },
117 },102 },
118 else => .{103 else => .{
119 .handle = std.posix.STDIN_FILENO,104 .handle = std.posix.STDIN_FILENO,
lib/std/Io/Threaded.zig+9-27
...@@ -2759,12 +2759,7 @@ fn dirCreateDirPathOpenWasi(...@@ -2759,12 +2759,7 @@ fn dirCreateDirPathOpenWasi(
27592759
2760fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat {2760fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat {
2761 const t: *Threaded = @ptrCast(@alignCast(userdata));2761 const t: *Threaded = @ptrCast(@alignCast(userdata));
2762 const file: File = if (is_windows) .{2762 const file: File = .{ .handle = dir.handle };
2763 .handle = dir.handle,
2764 .flags = .{ .nonblocking = false },
2765 } else .{
2766 .handle = dir.handle,
2767 };
2768 return fileStat(t, file);2763 return fileStat(t, file);
2769}2764}
27702765
...@@ -3686,10 +3681,7 @@ fn dirCreateFileWindows(...@@ -3686,10 +3681,7 @@ fn dirCreateFileWindows(
3686 errdefer windows.CloseHandle(handle);3681 errdefer windows.CloseHandle(handle);
36873682
3688 const exclusive = switch (flags.lock) {3683 const exclusive = switch (flags.lock) {
3689 .none => return .{3684 .none => return .{ .handle = handle },
3690 .handle = handle,
3691 .flags = .{ .nonblocking = false },
3692 },
3693 .shared => false,3685 .shared => false,
3694 .exclusive => true,3686 .exclusive => true,
3695 };3687 };
...@@ -3709,10 +3701,7 @@ fn dirCreateFileWindows(...@@ -3709,10 +3701,7 @@ fn dirCreateFileWindows(
3709 )) {3701 )) {
3710 .SUCCESS => {3702 .SUCCESS => {
3711 syscall.finish();3703 syscall.finish();
3712 return .{3704 return .{ .handle = handle };
3713 .handle = handle,
3714 .flags = .{ .nonblocking = false },
3715 };
3716 },3705 },
3717 .INSUFFICIENT_RESOURCES => return syscall.fail(error.SystemResources),3706 .INSUFFICIENT_RESOURCES => return syscall.fail(error.SystemResources),
3718 .LOCK_NOT_GRANTED => return syscall.fail(error.WouldBlock),3707 .LOCK_NOT_GRANTED => return syscall.fail(error.WouldBlock),
...@@ -4287,10 +4276,7 @@ pub fn dirOpenFileWtf16(...@@ -4287,10 +4276,7 @@ pub fn dirOpenFileWtf16(
4287 errdefer w.CloseHandle(handle);4276 errdefer w.CloseHandle(handle);
42884277
4289 const exclusive = switch (flags.lock) {4278 const exclusive = switch (flags.lock) {
4290 .none => return .{4279 .none => return .{ .handle = handle },
4291 .handle = handle,
4292 .flags = .{ .nonblocking = false },
4293 },
4294 .shared => false,4280 .shared => false,
4295 .exclusive => true,4281 .exclusive => true,
4296 };4282 };
...@@ -4313,10 +4299,7 @@ pub fn dirOpenFileWtf16(...@@ -4313,10 +4299,7 @@ pub fn dirOpenFileWtf16(
4313 .ACCESS_VIOLATION => |err| return syscall.ntstatusBug(err), // bad io_status_block pointer4299 .ACCESS_VIOLATION => |err| return syscall.ntstatusBug(err), // bad io_status_block pointer
4314 else => |status| return syscall.unexpectedNtstatus(status),4300 else => |status| return syscall.unexpectedNtstatus(status),
4315 };4301 };
4316 return .{4302 return .{ .handle = handle };
4317 .handle = handle,
4318 .flags = .{ .nonblocking = false },
4319 };
4320}4303}
43214304
4322fn dirOpenFileWasi(4305fn dirOpenFileWasi(
...@@ -8271,7 +8254,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us...@@ -8271,7 +8254,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us
8271 try syscall.checkCancel();8254 try syscall.checkCancel();
8272 continue;8255 continue;
8273 },8256 },
8274 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // wrong value for flags.nonblocking8257 .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), // streaming read of async mode file
8275 else => |status| return syscall.unexpectedNtstatus(status),8258 else => |status| return syscall.unexpectedNtstatus(status),
8276 }8259 }
8277 }8260 }
...@@ -14363,9 +14346,9 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro...@@ -14363,9 +14346,9 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro
14363 return .{14346 return .{
14364 .id = piProcInfo.hProcess,14347 .id = piProcInfo.hProcess,
14365 .thread_handle = piProcInfo.hThread,14348 .thread_handle = piProcInfo.hThread,
14366 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,14349 .stdin = if (g_hChildStd_IN_Wr) |h| .{ .handle = h } else null,
14367 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,14350 .stdout = if (g_hChildStd_OUT_Rd) |h| .{ .handle = h } else null,
14368 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h, .flags = .{ .nonblocking = true } } else null,14351 .stderr = if (g_hChildStd_ERR_Rd) |h| .{ .handle = h } else null,
14369 .request_resource_usage_statistics = options.request_resource_usage_statistics,14352 .request_resource_usage_statistics = options.request_resource_usage_statistics,
14370 };14353 };
14371}14354}
...@@ -15499,7 +15482,6 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File {...@@ -15499,7 +15482,6 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File {
15499 .pointer => @ptrFromInt(int),15482 .pointer => @ptrFromInt(int),
15500 else => return error.UnsupportedOperation,15483 else => return error.UnsupportedOperation,
15501 },15484 },
15502 .flags = if (is_windows) .{ .nonblocking = true } else .{},
15503 };15485 };
15504}15486}
1550515487
lib/std/Progress.zig-1
...@@ -979,7 +979,6 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff...@@ -979,7 +979,6 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
979 if (main_parent == .unused) continue;979 if (main_parent == .unused) continue;
980 const file: Io.File = .{980 const file: Io.File = .{
981 .handle = main_storage.getIpcFd() orelse continue,981 .handle = main_storage.getIpcFd() orelse continue,
982 .flags = if (is_windows) .{ .nonblocking = true } else .{},
983 };982 };
984 const opt_saved_metadata = findOld(file.handle, old_ipc_metadata_fds, old_ipc_metadata);983 const opt_saved_metadata = findOld(file.handle, old_ipc_metadata_fds, old_ipc_metadata);
985 var bytes_read: usize = 0;984 var bytes_read: usize = 0;