authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-26 16:41:16-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-26 19:58:56-08:00
log252c4e57c68d8ed0c2eecc17dfa5f6c63e672df2
treee983f35e8dae664e3276cd735c9af93ff70fd27d
parent28810f5e3d41597116773b2eb6686f3d8e272b36

std.Progress: fix compilation on Windows

by using std.Io.File.readStreaming rather than posix.read

1 files changed, 23 insertions(+), 22 deletions(-)

lib/std/Progress.zig+23-22
...@@ -127,20 +127,20 @@ pub const Node = struct {...@@ -127,20 +127,20 @@ pub const Node = struct {
127 name: [max_name_len]u8 align(@alignOf(usize)),127 name: [max_name_len]u8 align(@alignOf(usize)),
128128
129 /// Not thread-safe.129 /// Not thread-safe.
130 fn getIpcFd(s: Storage) ?posix.fd_t {130 fn getIpcFd(s: Storage) ?Io.File.Handle {
131 return if (s.estimated_total_count == std.math.maxInt(u32)) switch (@typeInfo(posix.fd_t)) {131 return if (s.estimated_total_count == std.math.maxInt(u32)) switch (@typeInfo(Io.File.Handle)) {
132 .int => @bitCast(s.completed_count),132 .int => @bitCast(s.completed_count),
133 .pointer => @ptrFromInt(s.completed_count),133 .pointer => @ptrFromInt(s.completed_count),
134 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),134 else => @compileError("unsupported fd_t of " ++ @typeName(Io.File.Handle)),
135 } else null;135 } else null;
136 }136 }
137137
138 /// Thread-safe.138 /// Thread-safe.
139 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {139 fn setIpcFd(s: *Storage, fd: Io.File.Handle) void {
140 const integer: u32 = switch (@typeInfo(posix.fd_t)) {140 const integer: u32 = switch (@typeInfo(Io.File.Handle)) {
141 .int => @bitCast(fd),141 .int => @bitCast(fd),
142 .pointer => @intFromPtr(fd),142 .pointer => @intFromPtr(fd),
143 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),143 else => @compileError("unsupported fd_t of " ++ @typeName(Io.File.Handle)),
144 };144 };
145 // `estimated_total_count` max int indicates the special state that145 // `estimated_total_count` max int indicates the special state that
146 // causes `completed_count` to be treated as a file descriptor, so146 // causes `completed_count` to be treated as a file descriptor, so
...@@ -340,7 +340,7 @@ pub const Node = struct {...@@ -340,7 +340,7 @@ pub const Node = struct {
340 }340 }
341341
342 /// Posix-only. Used by `std.process.Child`. Thread-safe.342 /// Posix-only. Used by `std.process.Child`. Thread-safe.
343 pub fn setIpcFd(node: Node, fd: posix.fd_t) void {343 pub fn setIpcFd(node: Node, fd: Io.File.Handle) void {
344 const index = node.index.unwrap() orelse return;344 const index = node.index.unwrap() orelse return;
345 assert(fd >= 0);345 assert(fd >= 0);
346 assert(fd != posix.STDOUT_FILENO);346 assert(fd != posix.STDOUT_FILENO);
...@@ -351,14 +351,14 @@ pub const Node = struct {...@@ -351,14 +351,14 @@ pub const Node = struct {
351351
352 /// Posix-only. Thread-safe. Assumes the node is storing an IPC file352 /// Posix-only. Thread-safe. Assumes the node is storing an IPC file
353 /// descriptor.353 /// descriptor.
354 pub fn getIpcFd(node: Node) ?posix.fd_t {354 pub fn getIpcFd(node: Node) ?Io.File.Handle {
355 const index = node.index.unwrap() orelse return null;355 const index = node.index.unwrap() orelse return null;
356 const storage = storageByIndex(index);356 const storage = storageByIndex(index);
357 const int = @atomicLoad(u32, &storage.completed_count, .monotonic);357 const int = @atomicLoad(u32, &storage.completed_count, .monotonic);
358 return switch (@typeInfo(posix.fd_t)) {358 return switch (@typeInfo(Io.File.Handle)) {
359 .int => @bitCast(int),359 .int => @bitCast(int),
360 .pointer => @ptrFromInt(int),360 .pointer => @ptrFromInt(int),
361 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),361 else => @compileError("unsupported fd_t of " ++ @typeName(Io.File.Handle)),
362 };362 };
363 }363 }
364364
...@@ -479,10 +479,10 @@ pub fn start(io: Io, options: Options) Node {...@@ -479,10 +479,10 @@ pub fn start(io: Io, options: Options) Node {
479 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {479 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {
480 global_progress.update_worker = io.concurrent(ipcThreadRun, .{480 global_progress.update_worker = io.concurrent(ipcThreadRun, .{
481 io,481 io,
482 @as(Io.File, .{ .handle = switch (@typeInfo(posix.fd_t)) {482 @as(Io.File, .{ .handle = switch (@typeInfo(Io.File.Handle)) {
483 .int => ipc_fd,483 .int => ipc_fd,
484 .pointer => @ptrFromInt(ipc_fd),484 .pointer => @ptrFromInt(ipc_fd),
485 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),485 else => @compileError("unsupported fd_t of " ++ @typeName(Io.File.Handle)),
486 } }),486 } }),
487 }) catch |err| {487 }) catch |err| {
488 global_progress.start_failure = .{ .spawn_ipc_worker = err };488 global_progress.start_failure = .{ .spawn_ipc_worker = err };
...@@ -934,11 +934,11 @@ const SavedMetadata = struct {...@@ -934,11 +934,11 @@ const SavedMetadata = struct {
934const Fd = enum(i32) {934const Fd = enum(i32) {
935 _,935 _,
936936
937 fn init(fd: posix.fd_t) Fd {937 fn init(fd: Io.File.Handle) Fd {
938 return @enumFromInt(if (is_windows) @as(isize, @bitCast(@intFromPtr(fd))) else fd);938 return @enumFromInt(if (is_windows) @as(isize, @bitCast(@intFromPtr(fd))) else fd);
939 }939 }
940940
941 fn get(fd: Fd) posix.fd_t {941 fn get(fd: Fd) Io.File.Handle {
942 return if (is_windows)942 return if (is_windows)
943 @ptrFromInt(@as(usize, @bitCast(@as(isize, @intFromEnum(fd)))))943 @ptrFromInt(@as(usize, @bitCast(@as(isize, @intFromEnum(fd)))))
944 else944 else
...@@ -949,6 +949,7 @@ const Fd = enum(i32) {...@@ -949,6 +949,7 @@ const Fd = enum(i32) {
949var ipc_metadata_len: u8 = 0;949var ipc_metadata_len: u8 = 0;
950950
951fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buffer) usize {951fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buffer) usize {
952 const io = global_progress.io;
952 const ipc_metadata_fds_copy = &serialized_buffer.ipc_metadata_fds_copy;953 const ipc_metadata_fds_copy = &serialized_buffer.ipc_metadata_fds_copy;
953 const ipc_metadata_copy = &serialized_buffer.ipc_metadata_copy;954 const ipc_metadata_copy = &serialized_buffer.ipc_metadata_copy;
954 const ipc_metadata_fds = &serialized_buffer.ipc_metadata_fds;955 const ipc_metadata_fds = &serialized_buffer.ipc_metadata_fds;
...@@ -967,11 +968,11 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff...@@ -967,11 +968,11 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
967 0..,968 0..,
968 ) |main_parent, *main_storage, main_index| {969 ) |main_parent, *main_storage, main_index| {
969 if (main_parent == .unused) continue;970 if (main_parent == .unused) continue;
970 const fd = main_storage.getIpcFd() orelse continue;971 const file: Io.File = .{ .handle = main_storage.getIpcFd() orelse continue };
971 const opt_saved_metadata = findOld(fd, old_ipc_metadata_fds, old_ipc_metadata);972 const opt_saved_metadata = findOld(file.handle, old_ipc_metadata_fds, old_ipc_metadata);
972 var bytes_read: usize = 0;973 var bytes_read: usize = 0;
973 while (true) {974 while (true) {
974 const n = posix.read(fd, pipe_buf[bytes_read..]) catch |err| switch (err) {975 const n = file.readStreaming(io, &.{pipe_buf[bytes_read..]}) catch |err| switch (err) {
975 error.WouldBlock => break,976 error.WouldBlock => break,
976 else => |e| {977 else => |e| {
977 std.log.debug("failed to read child progress data: {t}", .{e});978 std.log.debug("failed to read child progress data: {t}", .{e});
...@@ -1000,7 +1001,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff...@@ -1000,7 +1001,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
1000 // Ignore all but the last message on the pipe.1001 // Ignore all but the last message on the pipe.
1001 var input: []u8 = pipe_buf[0..bytes_read];1002 var input: []u8 = pipe_buf[0..bytes_read];
1002 if (input.len == 0) {1003 if (input.len == 0) {
1003 serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, opt_saved_metadata, 0, fd);1004 serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, opt_saved_metadata, 0, file.handle);
1004 continue;1005 continue;
1005 }1006 }
10061007
...@@ -1010,7 +1011,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff...@@ -1010,7 +1011,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
1010 if (input.len < expected_bytes) {1011 if (input.len < expected_bytes) {
1011 // Ignore short reads. We'll handle the next full message when it comes instead.1012 // Ignore short reads. We'll handle the next full message when it comes instead.
1012 const remaining_read_trash_bytes: u16 = @intCast(expected_bytes - input.len);1013 const remaining_read_trash_bytes: u16 = @intCast(expected_bytes - input.len);
1013 serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, opt_saved_metadata, remaining_read_trash_bytes, fd);1014 serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, opt_saved_metadata, remaining_read_trash_bytes, file.handle);
1014 continue :main_loop;1015 continue :main_loop;
1015 }1016 }
1016 if (input.len > expected_bytes) {1017 if (input.len > expected_bytes) {
...@@ -1028,7 +1029,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff...@@ -1028,7 +1029,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
1028 const nodes_len: u8 = @intCast(@min(parents.len - 1, serialized_buffer.storage.len - serialized_len));1029 const nodes_len: u8 = @intCast(@min(parents.len - 1, serialized_buffer.storage.len - serialized_len));
10291030
1030 // Remember in case the pipe is empty on next update.1031 // Remember in case the pipe is empty on next update.
1031 ipc_metadata_fds[ipc_metadata_len] = Fd.init(fd);1032 ipc_metadata_fds[ipc_metadata_len] = Fd.init(file.handle);
1032 ipc_metadata[ipc_metadata_len] = .{1033 ipc_metadata[ipc_metadata_len] = .{
1033 .remaining_read_trash_bytes = 0,1034 .remaining_read_trash_bytes = 0,
1034 .start_index = @intCast(serialized_len),1035 .start_index = @intCast(serialized_len),
...@@ -1086,7 +1087,7 @@ fn copyRoot(dest: *Node.Storage, src: *align(1) Node.Storage) void {...@@ -1086,7 +1087,7 @@ fn copyRoot(dest: *Node.Storage, src: *align(1) Node.Storage) void {
1086}1087}
10871088
1088fn findOld(1089fn findOld(
1089 ipc_fd: posix.fd_t,1090 ipc_fd: Io.File.Handle,
1090 old_metadata_fds: []Fd,1091 old_metadata_fds: []Fd,
1091 old_metadata: []SavedMetadata,1092 old_metadata: []SavedMetadata,
1092) ?*SavedMetadata {1093) ?*SavedMetadata {
...@@ -1104,7 +1105,7 @@ fn useSavedIpcData(...@@ -1104,7 +1105,7 @@ fn useSavedIpcData(
1104 main_index: usize,1105 main_index: usize,
1105 opt_saved_metadata: ?*SavedMetadata,1106 opt_saved_metadata: ?*SavedMetadata,
1106 remaining_read_trash_bytes: u16,1107 remaining_read_trash_bytes: u16,
1107 fd: posix.fd_t,1108 fd: Io.File.Handle,
1108) usize {1109) usize {
1109 const parents_copy = &serialized_buffer.parents_copy;1110 const parents_copy = &serialized_buffer.parents_copy;
1110 const storage_copy = &serialized_buffer.storage_copy;1111 const storage_copy = &serialized_buffer.storage_copy;