| ... | @@ -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; |
| 90 | | 90 | |
| 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 | } |
| 93 | | 100 | |
| 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 | } |
| 389 | | 396 | |
| 390 | fn ipcThreadRun(fd: posix.fd_t) void { | 397 | fn ipcThreadRun(fd: posix.fd_t) anyerror!void { |
| 391 | { | 398 | { |
| 392 | _ = wait(global_progress.initial_delay_ns); | 399 | _ = wait(global_progress.initial_delay_ns); |
| 393 | | 400 | |
| ... | @@ -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; |
| 396 | | 403 | |
| 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 | } |
| 400 | | 409 | |
| 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(); |
| 406 | | 415 | |
| 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 | } |
| 411 | | 422 | |
| ... | @@ -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); |
| 489 | | 500 | |
| 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 | } |
| 491 | | 505 | |
| 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; |
| 541 | | 555 | |
| 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 read | 585 | // 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 read | 593 | // 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 | }; |
| 594 | | 608 | |
| 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; |
| 645 | | 660 | |
| | 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]; |
| 648 | | 671 | |
| ... | @@ -793,7 +816,7 @@ fn write(buf: []const u8) void { | ... | @@ -793,7 +816,7 @@ fn write(buf: []const u8) void { |
| 793 | }; | 816 | }; |
| 794 | } | 817 | } |
| 795 | | 818 | |
| 796 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) void { | 819 | fn 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 | } |
| 824 | | 851 | |