authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-23 21:04:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-27 20:56:48-07:00
logf6873c6b00544923d5699737651f2bc4fe29fd06
tree27c89140d69406200d29bec5b7fb69e751a70dd5
parentc01cfde6882840980cbf63593eafb5e1090b1ff0

std.Progress: fix using saved IPC data

also fix handling of BrokenPipe also fix continuing wrong loop in error conditions

1 files changed, 39 insertions(+), 12 deletions(-)

lib/std/Progress.zig+39-12
......@@ -88,7 +88,14 @@ pub const Node = struct {
8888 if (s.estimated_total_count != std.math.maxInt(u32))
8989 return null;
9090
91 return @bitCast(s.completed_count);
91 const low: u16 = @truncate(s.completed_count);
92 return low;
93 }
94
95 fn getMainStorageIndex(s: Storage) Node.Index {
96 assert(s.estimated_total_count == std.math.maxInt(u32));
97 const i: u16 = @truncate(s.completed_count >> 16);
98 return @enumFromInt(i);
9299 }
93100
94101 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {
......@@ -387,7 +394,7 @@ fn updateThreadRun() void {
387394 }
388395}
389396
390fn ipcThreadRun(fd: posix.fd_t) void {
397fn ipcThreadRun(fd: posix.fd_t) anyerror!void {
391398 {
392399 _ = wait(global_progress.initial_delay_ns);
393400
......@@ -395,7 +402,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {
395402 return;
396403
397404 const serialized = serialize();
398 writeIpc(fd, serialized);
405 writeIpc(fd, serialized) catch |err| switch (err) {
406 error.BrokenPipe => return,
407 };
399408 }
400409
401410 while (true) {
......@@ -405,7 +414,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {
405414 return clearTerminal();
406415
407416 const serialized = serialize();
408 writeIpc(fd, serialized);
417 writeIpc(fd, serialized) catch |err| switch (err) {
418 error.BrokenPipe => return,
419 };
409420 }
410421}
411422
......@@ -487,7 +498,10 @@ fn serialize() Serialized {
487498 dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic);
488499 dest_storage.estimated_total_count = @atomicLoad(u32, &storage_ptr.estimated_total_count, .monotonic);
489500
490 any_ipc = any_ipc or dest_storage.getIpcFd() != null;
501 if (dest_storage.getIpcFd() != null) {
502 any_ipc = true;
503 dest_storage.completed_count |= @as(u32, @intCast(i)) << 16;
504 }
491505
492506 const end_parent = @atomicLoad(Node.Parent, parent_ptr, .seq_cst);
493507 if (begin_parent == end_parent) {
......@@ -539,7 +553,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
539553 var serialized_len = start_serialized_len;
540554 var pipe_buf: [4096]u8 align(4) = undefined;
541555
542 for (
556 main_loop: for (
543557 serialized_node_parents_buffer[0..serialized_len],
544558 serialized_node_storage_buffer[0..serialized_len],
545559 0..,
......@@ -554,7 +568,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
554568 std.log.warn("failed to read child progress data: {s}", .{@errorName(e)});
555569 main_storage.completed_count = 0;
556570 main_storage.estimated_total_count = 0;
557 continue;
571 continue :main_loop;
558572 },
559573 };
560574 }
......@@ -570,7 +584,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
570584 std.log.warn("short read: {d} out of 4 header bytes", .{input.len});
571585 // TODO keep track of the short read to trash odd bytes with the next read
572586 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);
573 continue;
587 continue :main_loop;
574588 }
575589 const subtree_len = std.mem.readInt(u32, input[0..4], .little);
576590 const expected_bytes = 4 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent));
......@@ -578,7 +592,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
578592 std.log.warn("short read: {d} out of {d} ({d} nodes)", .{ input.len, expected_bytes, subtree_len });
579593 // TODO keep track of the short read to trash odd bytes with the next read
580594 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);
581 continue;
595 continue :main_loop;
582596 }
583597 if (input.len > expected_bytes) {
584598 input = @alignCast(input[expected_bytes..]);
......@@ -593,7 +607,8 @@ fn serializeIpc(start_serialized_len: usize) usize {
593607 };
594608
595609 // Remember in case the pipe is empty on next update.
596 @as(*SavedMetadata, @ptrCast(&main_storage.name)).* = .{
610 const real_storage: *Node.Storage = Node.storageByIndex(main_storage.getMainStorageIndex());
611 @as(*SavedMetadata, @ptrCast(&real_storage.name)).* = .{
597612 .start_index = @intCast(serialized_len),
598613 .nodes_len = @intCast(parents.len),
599614 .main_index = @intCast(main_index),
......@@ -643,6 +658,14 @@ fn useSavedIpcData(start_serialized_len: usize, main_storage: *Node.Storage, mai
643658 const nodes_len = saved_metadata.nodes_len;
644659 const old_main_index = saved_metadata.main_index;
645660
661 const real_storage: *Node.Storage = Node.storageByIndex(main_storage.getMainStorageIndex());
662 @as(*SavedMetadata, @ptrCast(&real_storage.name)).* = .{
663 .start_index = @intCast(start_serialized_len),
664 .nodes_len = nodes_len,
665 .main_index = @intCast(main_index),
666 .flags = .saved,
667 };
668
646669 const parents = parents_copy[start_index..][0 .. nodes_len - 1];
647670 const storage = storage_copy[start_index..][0 .. nodes_len - 1];
648671
......@@ -793,7 +816,7 @@ fn write(buf: []const u8) void {
793816 };
794817}
795818
796fn writeIpc(fd: posix.fd_t, serialized: Serialized) void {
819fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void {
797820 assert(serialized.parents.len == serialized.storage.len);
798821 const serialized_len: u32 = @intCast(serialized.parents.len);
799822 const header = std.mem.asBytes(&serialized_len);
......@@ -818,7 +841,11 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) void {
818841 }
819842 } else |err| switch (err) {
820843 error.WouldBlock => {},
821 else => |e| std.log.warn("failed to send progress to parent process: {s}", .{@errorName(e)}),
844 error.BrokenPipe => return error.BrokenPipe,
845 else => |e| {
846 std.log.warn("failed to send progress to parent process: {s}", .{@errorName(e)});
847 return error.BrokenPipe;
848 },
822849 }
823850}
824851