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 {...@@ -88,7 +88,14 @@ pub const Node = struct {
88 if (s.estimated_total_count != std.math.maxInt(u32))88 if (s.estimated_total_count != std.math.maxInt(u32))
89 return null;89 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);
92 }99 }
93100
94 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {101 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {
...@@ -387,7 +394,7 @@ fn updateThreadRun() void {...@@ -387,7 +394,7 @@ fn updateThreadRun() void {
387 }394 }
388}395}
389396
390fn ipcThreadRun(fd: posix.fd_t) void {397fn ipcThreadRun(fd: posix.fd_t) anyerror!void {
391 {398 {
392 _ = wait(global_progress.initial_delay_ns);399 _ = wait(global_progress.initial_delay_ns);
393400
...@@ -395,7 +402,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {...@@ -395,7 +402,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {
395 return;402 return;
396403
397 const serialized = serialize();404 const serialized = serialize();
398 writeIpc(fd, serialized);405 writeIpc(fd, serialized) catch |err| switch (err) {
406 error.BrokenPipe => return,
407 };
399 }408 }
400409
401 while (true) {410 while (true) {
...@@ -405,7 +414,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {...@@ -405,7 +414,9 @@ fn ipcThreadRun(fd: posix.fd_t) void {
405 return clearTerminal();414 return clearTerminal();
406415
407 const serialized = serialize();416 const serialized = serialize();
408 writeIpc(fd, serialized);417 writeIpc(fd, serialized) catch |err| switch (err) {
418 error.BrokenPipe => return,
419 };
409 }420 }
410}421}
411422
...@@ -487,7 +498,10 @@ fn serialize() Serialized {...@@ -487,7 +498,10 @@ fn serialize() Serialized {
487 dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic);498 dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic);
488 dest_storage.estimated_total_count = @atomicLoad(u32, &storage_ptr.estimated_total_count, .monotonic);499 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
492 const end_parent = @atomicLoad(Node.Parent, parent_ptr, .seq_cst);506 const end_parent = @atomicLoad(Node.Parent, parent_ptr, .seq_cst);
493 if (begin_parent == end_parent) {507 if (begin_parent == end_parent) {
...@@ -539,7 +553,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -539,7 +553,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
539 var serialized_len = start_serialized_len;553 var serialized_len = start_serialized_len;
540 var pipe_buf: [4096]u8 align(4) = undefined;554 var pipe_buf: [4096]u8 align(4) = undefined;
541555
542 for (556 main_loop: for (
543 serialized_node_parents_buffer[0..serialized_len],557 serialized_node_parents_buffer[0..serialized_len],
544 serialized_node_storage_buffer[0..serialized_len],558 serialized_node_storage_buffer[0..serialized_len],
545 0..,559 0..,
...@@ -554,7 +568,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -554,7 +568,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
554 std.log.warn("failed to read child progress data: {s}", .{@errorName(e)});568 std.log.warn("failed to read child progress data: {s}", .{@errorName(e)});
555 main_storage.completed_count = 0;569 main_storage.completed_count = 0;
556 main_storage.estimated_total_count = 0;570 main_storage.estimated_total_count = 0;
557 continue;571 continue :main_loop;
558 },572 },
559 };573 };
560 }574 }
...@@ -570,7 +584,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -570,7 +584,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
570 std.log.warn("short read: {d} out of 4 header bytes", .{input.len});584 std.log.warn("short read: {d} out of 4 header bytes", .{input.len});
571 // TODO keep track of the short read to trash odd bytes with the next read585 // TODO keep track of the short read to trash odd bytes with the next read
572 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);586 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);
573 continue;587 continue :main_loop;
574 }588 }
575 const subtree_len = std.mem.readInt(u32, input[0..4], .little);589 const subtree_len = std.mem.readInt(u32, input[0..4], .little);
576 const expected_bytes = 4 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent));590 const expected_bytes = 4 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent));
...@@ -578,7 +592,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -578,7 +592,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
578 std.log.warn("short read: {d} out of {d} ({d} nodes)", .{ input.len, expected_bytes, subtree_len });592 std.log.warn("short read: {d} out of {d} ({d} nodes)", .{ input.len, expected_bytes, subtree_len });
579 // TODO keep track of the short read to trash odd bytes with the next read593 // TODO keep track of the short read to trash odd bytes with the next read
580 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);594 serialized_len = useSavedIpcData(serialized_len, main_storage, main_index);
581 continue;595 continue :main_loop;
582 }596 }
583 if (input.len > expected_bytes) {597 if (input.len > expected_bytes) {
584 input = @alignCast(input[expected_bytes..]);598 input = @alignCast(input[expected_bytes..]);
...@@ -593,7 +607,8 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -593,7 +607,8 @@ fn serializeIpc(start_serialized_len: usize) usize {
593 };607 };
594608
595 // Remember in case the pipe is empty on next update.609 // 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)).* = .{
597 .start_index = @intCast(serialized_len),612 .start_index = @intCast(serialized_len),
598 .nodes_len = @intCast(parents.len),613 .nodes_len = @intCast(parents.len),
599 .main_index = @intCast(main_index),614 .main_index = @intCast(main_index),
...@@ -643,6 +658,14 @@ fn useSavedIpcData(start_serialized_len: usize, main_storage: *Node.Storage, mai...@@ -643,6 +658,14 @@ fn useSavedIpcData(start_serialized_len: usize, main_storage: *Node.Storage, mai
643 const nodes_len = saved_metadata.nodes_len;658 const nodes_len = saved_metadata.nodes_len;
644 const old_main_index = saved_metadata.main_index;659 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
646 const parents = parents_copy[start_index..][0 .. nodes_len - 1];669 const parents = parents_copy[start_index..][0 .. nodes_len - 1];
647 const storage = storage_copy[start_index..][0 .. nodes_len - 1];670 const storage = storage_copy[start_index..][0 .. nodes_len - 1];
648671
...@@ -793,7 +816,7 @@ fn write(buf: []const u8) void {...@@ -793,7 +816,7 @@ fn write(buf: []const u8) void {
793 };816 };
794}817}
795818
796fn writeIpc(fd: posix.fd_t, serialized: Serialized) void {819fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void {
797 assert(serialized.parents.len == serialized.storage.len);820 assert(serialized.parents.len == serialized.storage.len);
798 const serialized_len: u32 = @intCast(serialized.parents.len);821 const serialized_len: u32 = @intCast(serialized.parents.len);
799 const header = std.mem.asBytes(&serialized_len);822 const header = std.mem.asBytes(&serialized_len);
...@@ -818,7 +841,11 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) void {...@@ -818,7 +841,11 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) void {
818 }841 }
819 } else |err| switch (err) {842 } else |err| switch (err) {
820 error.WouldBlock => {},843 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 },
822 }849 }
823}850}
824851