authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-24 10:39:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-27 20:56:48-07:00
log70e39c1a20842a2e1579d5ff76845cd1121a907b
tree2a319f54a05a4ce1e470b7cea34b75f7e9c8d479
parent2233d95b0f5edce5b2e0105ef78847fabe86f4d6

std.Progress: fixes

* bump default statically allocated resources * debug help when multiple instances of std.Progress are initialized * only handle sigwinch on supported operating systems * handle when reading from the pipe returns 0 bytes * avoid printing more lines than rows

1 files changed, 49 insertions(+), 16 deletions(-)

lib/std/Progress.zig+49-16
...@@ -293,12 +293,14 @@ var global_progress: Progress = .{...@@ -293,12 +293,14 @@ var global_progress: Progress = .{
293 .node_end_index = 0,293 .node_end_index = 0,
294};294};
295295
296const default_node_storage_buffer_len = 100;296const default_node_storage_buffer_len = 200;
297var node_parents_buffer: [default_node_storage_buffer_len]Node.Parent = undefined;297var node_parents_buffer: [default_node_storage_buffer_len]Node.Parent = undefined;
298var node_storage_buffer: [default_node_storage_buffer_len]Node.Storage = undefined;298var node_storage_buffer: [default_node_storage_buffer_len]Node.Storage = undefined;
299var node_freelist_buffer: [default_node_storage_buffer_len]Node.OptionalIndex = undefined;299var node_freelist_buffer: [default_node_storage_buffer_len]Node.OptionalIndex = undefined;
300300
301var default_draw_buffer: [2000]u8 = undefined;301var default_draw_buffer: [4096]u8 = undefined;
302
303var debug_start_trace = std.debug.Trace.init;
302304
303/// Initializes a global Progress instance.305/// Initializes a global Progress instance.
304///306///
...@@ -307,7 +309,11 @@ var default_draw_buffer: [2000]u8 = undefined;...@@ -307,7 +309,11 @@ var default_draw_buffer: [2000]u8 = undefined;
307/// Call `Node.end` when done.309/// Call `Node.end` when done.
308pub fn start(options: Options) Node {310pub fn start(options: Options) Node {
309 // Ensure there is only 1 global Progress object.311 // Ensure there is only 1 global Progress object.
310 assert(global_progress.node_end_index == 0);312 if (global_progress.node_end_index != 0) {
313 debug_start_trace.dump();
314 unreachable;
315 }
316 debug_start_trace.add("first initialized here");
311317
312 @memset(global_progress.node_parents, .unused);318 @memset(global_progress.node_parents, .unused);
313 const root_node = Node.init(@enumFromInt(0), .none, options.root_name, options.estimated_total_items);319 const root_node = Node.init(@enumFromInt(0), .none, options.root_name, options.estimated_total_items);
...@@ -347,14 +353,16 @@ pub fn start(options: Options) Node {...@@ -347,14 +353,16 @@ pub fn start(options: Options) Node {
347 return .{ .index = .none };353 return .{ .index = .none };
348 }354 }
349355
350 var act: posix.Sigaction = .{356 if (have_sigwinch) {
351 .handler = .{ .sigaction = handleSigWinch },357 var act: posix.Sigaction = .{
352 .mask = posix.empty_sigset,358 .handler = .{ .sigaction = handleSigWinch },
353 .flags = (posix.SA.SIGINFO | posix.SA.RESTART),359 .mask = posix.empty_sigset,
354 };360 .flags = (posix.SA.SIGINFO | posix.SA.RESTART),
355 posix.sigaction(posix.SIG.WINCH, &act, null) catch |err| {361 };
356 std.log.warn("failed to install SIGWINCH signal handler for noticing terminal resizes: {s}", .{@errorName(err)});362 posix.sigaction(posix.SIG.WINCH, &act, null) catch |err| {
357 };363 std.log.warn("failed to install SIGWINCH signal handler for noticing terminal resizes: {s}", .{@errorName(err)});
364 };
365 }
358366
359 if (std.Thread.spawn(.{}, updateThreadRun, .{})) |thread| {367 if (std.Thread.spawn(.{}, updateThreadRun, .{})) |thread| {
360 global_progress.update_thread = thread;368 global_progress.update_thread = thread;
...@@ -595,7 +603,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -595,7 +603,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
595 const fd = main_storage.getIpcFd() orelse continue;603 const fd = main_storage.getIpcFd() orelse continue;
596 var bytes_read: usize = 0;604 var bytes_read: usize = 0;
597 while (true) {605 while (true) {
598 bytes_read += posix.read(fd, pipe_buf[bytes_read..]) catch |err| switch (err) {606 const n = posix.read(fd, pipe_buf[bytes_read..]) catch |err| switch (err) {
599 error.WouldBlock => break,607 error.WouldBlock => break,
600 else => |e| {608 else => |e| {
601 std.log.warn("failed to read child progress data: {s}", .{@errorName(e)});609 std.log.warn("failed to read child progress data: {s}", .{@errorName(e)});
...@@ -604,6 +612,8 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -604,6 +612,8 @@ fn serializeIpc(start_serialized_len: usize) usize {
604 continue :main_loop;612 continue :main_loop;
605 },613 },
606 };614 };
615 if (n == 0) break;
616 bytes_read += n;
607 }617 }
608 // Ignore all but the last message on the pipe.618 // Ignore all but the last message on the pipe.
609 var input: []align(2) u8 = pipe_buf[0..bytes_read];619 var input: []align(2) u8 = pipe_buf[0..bytes_read];
...@@ -831,12 +841,16 @@ fn computeNode(...@@ -831,12 +841,16 @@ fn computeNode(
831 i += 1;841 i += 1;
832 global_progress.newline_count += 1;842 global_progress.newline_count += 1;
833843
834 if (children[@intFromEnum(node_index)].child.unwrap()) |child| {844 if (global_progress.newline_count < global_progress.rows) {
835 i = computeNode(buf, i, serialized, children, child);845 if (children[@intFromEnum(node_index)].child.unwrap()) |child| {
846 i = computeNode(buf, i, serialized, children, child);
847 }
836 }848 }
837849
838 if (children[@intFromEnum(node_index)].sibling.unwrap()) |sibling| {850 if (global_progress.newline_count < global_progress.rows) {
839 i = computeNode(buf, i, serialized, children, sibling);851 if (children[@intFromEnum(node_index)].sibling.unwrap()) |sibling| {
852 i = computeNode(buf, i, serialized, children, sibling);
853 }
840 }854 }
841855
842 return i;856 return i;
...@@ -910,4 +924,23 @@ fn handleSigWinch(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque)...@@ -910,4 +924,23 @@ fn handleSigWinch(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque)
910 global_progress.redraw_event.set();924 global_progress.redraw_event.set();
911}925}
912926
927const have_sigwinch = switch (builtin.os.tag) {
928 .linux,
929 .plan9,
930 .solaris,
931 .netbsd,
932 .openbsd,
933 .haiku,
934 .macos,
935 .ios,
936 .watchos,
937 .tvos,
938 .visionos,
939 .dragonfly,
940 .freebsd,
941 => true,
942
943 else => false,
944};
945
913var stderr_mutex: std.Thread.Mutex = .{};946var stderr_mutex: std.Thread.Mutex = .{};