| ... | @@ -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 | }; |
| 295 | | 295 | |
| 296 | const default_node_storage_buffer_len = 100; | 296 | const default_node_storage_buffer_len = 200; |
| 297 | var node_parents_buffer: [default_node_storage_buffer_len]Node.Parent = undefined; | 297 | var node_parents_buffer: [default_node_storage_buffer_len]Node.Parent = undefined; |
| 298 | var node_storage_buffer: [default_node_storage_buffer_len]Node.Storage = undefined; | 298 | var node_storage_buffer: [default_node_storage_buffer_len]Node.Storage = undefined; |
| 299 | var node_freelist_buffer: [default_node_storage_buffer_len]Node.OptionalIndex = undefined; | 299 | var node_freelist_buffer: [default_node_storage_buffer_len]Node.OptionalIndex = undefined; |
| 300 | | 300 | |
| 301 | var default_draw_buffer: [2000]u8 = undefined; | 301 | var default_draw_buffer: [4096]u8 = undefined; |
| | 302 | |
| | 303 | var debug_start_trace = std.debug.Trace.init; |
| 302 | | 304 | |
| 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. |
| 308 | pub fn start(options: Options) Node { | 310 | pub 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"); |
| 311 | | 317 | |
| 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 | } |
| 349 | | 355 | |
| 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 | } |
| 358 | | 366 | |
| 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; |
| 833 | | 843 | |
| 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 | } |
| 837 | | 849 | |
| 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 | } |
| 841 | | 855 | |
| 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 | } |
| 912 | | 926 | |
| | 927 | const 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 | |
| 913 | var stderr_mutex: std.Thread.Mutex = .{}; | 946 | var stderr_mutex: std.Thread.Mutex = .{}; |