| ... | @@ -104,11 +104,11 @@ pub const Node = struct { | ... | @@ -104,11 +104,11 @@ pub const Node = struct { |
| 104 | } | 104 | } |
| 105 | }; | 105 | }; |
| 106 | | 106 | |
| 107 | const Parent = enum(u16) { | 107 | const Parent = enum(u8) { |
| 108 | /// Unallocated storage. | 108 | /// Unallocated storage. |
| 109 | unused = std.math.maxInt(u16) - 1, | 109 | unused = std.math.maxInt(u8) - 1, |
| 110 | /// Indicates root node. | 110 | /// Indicates root node. |
| 111 | none = std.math.maxInt(u16), | 111 | none = std.math.maxInt(u8), |
| 112 | /// Index into `node_storage`. | 112 | /// Index into `node_storage`. |
| 113 | _, | 113 | _, |
| 114 | | 114 | |
| ... | @@ -120,8 +120,8 @@ pub const Node = struct { | ... | @@ -120,8 +120,8 @@ pub const Node = struct { |
| 120 | } | 120 | } |
| 121 | }; | 121 | }; |
| 122 | | 122 | |
| 123 | const OptionalIndex = enum(u16) { | 123 | const OptionalIndex = enum(u8) { |
| 124 | none = std.math.maxInt(u16), | 124 | none = std.math.maxInt(u8), |
| 125 | /// Index into `node_storage`. | 125 | /// Index into `node_storage`. |
| 126 | _, | 126 | _, |
| 127 | | 127 | |
| ... | @@ -137,7 +137,7 @@ pub const Node = struct { | ... | @@ -137,7 +137,7 @@ pub const Node = struct { |
| 137 | }; | 137 | }; |
| 138 | | 138 | |
| 139 | /// Index into `node_storage`. | 139 | /// Index into `node_storage`. |
| 140 | const Index = enum(u16) { | 140 | const Index = enum(u8) { |
| 141 | _, | 141 | _, |
| 142 | | 142 | |
| 143 | fn toParent(i: @This()) Parent { | 143 | fn toParent(i: @This()) Parent { |
| ... | @@ -589,8 +589,6 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized { | ... | @@ -589,8 +589,6 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized { |
| 589 | }; | 589 | }; |
| 590 | } | 590 | } |
| 591 | | 591 | |
| 592 | var ipc_metadata_len: u16 = 0; | | |
| 593 | | | |
| 594 | const SavedMetadata = struct { | 592 | const SavedMetadata = struct { |
| 595 | ipc_fd: u16, | 593 | ipc_fd: u16, |
| 596 | main_index: u8, | 594 | main_index: u8, |
| ... | @@ -612,6 +610,9 @@ const SavedMetadata = struct { | ... | @@ -612,6 +610,9 @@ const SavedMetadata = struct { |
| 612 | } | 610 | } |
| 613 | }; | 611 | }; |
| 614 | | 612 | |
| | 613 | var ipc_metadata_len: u8 = 0; |
| | 614 | var remaining_read_trash_bytes: usize = 0; |
| | 615 | |
| 615 | fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buffer) usize { | 616 | fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buffer) usize { |
| 616 | const ipc_metadata_copy = &serialized_buffer.ipc_metadata_copy; | 617 | const ipc_metadata_copy = &serialized_buffer.ipc_metadata_copy; |
| 617 | const ipc_metadata = &serialized_buffer.ipc_metadata; | 618 | const ipc_metadata = &serialized_buffer.ipc_metadata; |
| ... | @@ -641,36 +642,43 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff | ... | @@ -641,36 +642,43 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 641 | }, | 642 | }, |
| 642 | }; | 643 | }; |
| 643 | if (n == 0) break; | 644 | if (n == 0) break; |
| | 645 | if (remaining_read_trash_bytes > 0) { |
| | 646 | assert(bytes_read == 0); |
| | 647 | if (remaining_read_trash_bytes >= n) { |
| | 648 | remaining_read_trash_bytes -= n; |
| | 649 | continue; |
| | 650 | } |
| | 651 | const src = pipe_buf[remaining_read_trash_bytes..n]; |
| | 652 | std.mem.copyForwards(u8, &pipe_buf, src); |
| | 653 | remaining_read_trash_bytes = 0; |
| | 654 | bytes_read = src.len; |
| | 655 | continue; |
| | 656 | } |
| 644 | bytes_read += n; | 657 | bytes_read += n; |
| 645 | } | 658 | } |
| 646 | // Ignore all but the last message on the pipe. | 659 | // Ignore all but the last message on the pipe. |
| 647 | var input: []align(2) u8 = pipe_buf[0..bytes_read]; | 660 | var input: []u8 = pipe_buf[0..bytes_read]; |
| 648 | if (input.len == 0) { | 661 | if (input.len == 0) { |
| 649 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); | 662 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); |
| 650 | continue; | 663 | continue; |
| 651 | } | 664 | } |
| 652 | | 665 | |
| 653 | const storage, const parents = while (true) { | 666 | const storage, const parents = while (true) { |
| 654 | if (input.len < 4) { | 667 | const subtree_len: usize = input[0]; |
| 655 | std.log.warn("short read: {d} out of 4 header bytes", .{input.len}); | 668 | const expected_bytes = 1 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent)); |
| 656 | // TODO keep track of the short read to trash odd bytes with the next read | | |
| 657 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); | | |
| 658 | continue :main_loop; | | |
| 659 | } | | |
| 660 | const subtree_len = std.mem.readInt(u32, input[0..4], .little); | | |
| 661 | const expected_bytes = 4 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent)); | | |
| 662 | if (input.len < expected_bytes) { | 669 | if (input.len < expected_bytes) { |
| 663 | std.log.warn("short read: {d} out of {d} ({d} nodes)", .{ input.len, expected_bytes, subtree_len }); | 670 | // Ignore short reads. We'll handle the next full message when it comes instead. |
| 664 | // TODO keep track of the short read to trash odd bytes with the next read | 671 | assert(remaining_read_trash_bytes == 0); |
| | 672 | remaining_read_trash_bytes = expected_bytes - input.len; |
| 665 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); | 673 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); |
| 666 | continue :main_loop; | 674 | continue :main_loop; |
| 667 | } | 675 | } |
| 668 | if (input.len > expected_bytes) { | 676 | if (input.len > expected_bytes) { |
| 669 | input = @alignCast(input[expected_bytes..]); | 677 | input = input[expected_bytes..]; |
| 670 | continue; | 678 | continue; |
| 671 | } | 679 | } |
| 672 | const storage_bytes = input[4..][0 .. subtree_len * @sizeOf(Node.Storage)]; | 680 | const storage_bytes = input[1..][0 .. subtree_len * @sizeOf(Node.Storage)]; |
| 673 | const parents_bytes = input[4 + storage_bytes.len ..][0 .. subtree_len * @sizeOf(Node.Parent)]; | 681 | const parents_bytes = input[1 + storage_bytes.len ..][0 .. subtree_len * @sizeOf(Node.Parent)]; |
| 674 | break .{ | 682 | break .{ |
| 675 | std.mem.bytesAsSlice(Node.Storage, storage_bytes), | 683 | std.mem.bytesAsSlice(Node.Storage, storage_bytes), |
| 676 | std.mem.bytesAsSlice(Node.Parent, parents_bytes), | 684 | std.mem.bytesAsSlice(Node.Parent, parents_bytes), |
| ... | @@ -722,7 +730,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff | ... | @@ -722,7 +730,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 722 | return serialized_len; | 730 | return serialized_len; |
| 723 | } | 731 | } |
| 724 | | 732 | |
| 725 | fn copyRoot(dest: *Node.Storage, src: *align(2) Node.Storage) void { | 733 | fn copyRoot(dest: *Node.Storage, src: *align(1) Node.Storage) void { |
| 726 | dest.* = .{ | 734 | dest.* = .{ |
| 727 | .completed_count = src.completed_count, | 735 | .completed_count = src.completed_count, |
| 728 | .estimated_total_count = src.estimated_total_count, | 736 | .estimated_total_count = src.estimated_total_count, |
| ... | @@ -937,7 +945,7 @@ fn write(buf: []const u8) void { | ... | @@ -937,7 +945,7 @@ fn write(buf: []const u8) void { |
| 937 | | 945 | |
| 938 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { | 946 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { |
| 939 | assert(serialized.parents.len == serialized.storage.len); | 947 | assert(serialized.parents.len == serialized.storage.len); |
| 940 | const serialized_len: u32 = @intCast(serialized.parents.len); | 948 | const serialized_len: u8 = @intCast(serialized.parents.len); |
| 941 | const header = std.mem.asBytes(&serialized_len); | 949 | const header = std.mem.asBytes(&serialized_len); |
| 942 | const storage = std.mem.sliceAsBytes(serialized.storage); | 950 | const storage = std.mem.sliceAsBytes(serialized.storage); |
| 943 | const parents = std.mem.sliceAsBytes(serialized.parents); | 951 | const parents = std.mem.sliceAsBytes(serialized.parents); |
| ... | @@ -977,7 +985,9 @@ fn maybeUpdateSize(resize_flag: bool) void { | ... | @@ -977,7 +985,9 @@ fn maybeUpdateSize(resize_flag: bool) void { |
| 977 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | 985 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 978 | | 986 | |
| 979 | if (windows.kernel32.GetConsoleScreenBufferInfo(fd, &info) == windows.FALSE) { | 987 | if (windows.kernel32.GetConsoleScreenBufferInfo(fd, &info) == windows.FALSE) { |
| 980 | @panic("TODO: handle this failure"); | 988 | std.log.debug("failed to determine terminal size; using conservative guess 80x25", .{}); |
| | 989 | global_progress.rows = 25; |
| | 990 | global_progress.cols = 80; |
| 981 | } | 991 | } |
| 982 | | 992 | |
| 983 | global_progress.rows = @intCast(info.dwSize.Y); | 993 | global_progress.rows = @intCast(info.dwSize.Y); |
| ... | @@ -995,7 +1005,9 @@ fn maybeUpdateSize(resize_flag: bool) void { | ... | @@ -995,7 +1005,9 @@ fn maybeUpdateSize(resize_flag: bool) void { |
| 995 | global_progress.rows = winsize.ws_row; | 1005 | global_progress.rows = winsize.ws_row; |
| 996 | global_progress.cols = winsize.ws_col; | 1006 | global_progress.cols = winsize.ws_col; |
| 997 | } else { | 1007 | } else { |
| 998 | @panic("TODO: handle this failure"); | 1008 | std.log.debug("failed to determine terminal size; using conservative guess 80x25", .{}); |
| | 1009 | global_progress.rows = 25; |
| | 1010 | global_progress.cols = 80; |
| 999 | } | 1011 | } |
| 1000 | } | 1012 | } |
| 1001 | } | 1013 | } |