@@ -86,17 +86,7 @@ pub const Node = struct {
8686 name : [max_name_len ]u8 ,
8787
8888 fn getIpcFd (s : Storage ) ? posix.fd_t {
89- if (s .estimated_total_count != std .math .maxInt (u32 ))
90- return null ;
91-
92- const low : u16 = @truncate (s .completed_count );
93- return low ;
94- }
95-
96- fn getMainStorageIndex (s : Storage ) Node.Index {
97- assert (s .estimated_total_count == std .math .maxInt (u32 ));
98- const i : u16 = @truncate (s .completed_count >> 16 );
99- return @enumFromInt (i );
89+ return if (s .estimated_total_count != std .math .maxInt (u32 )) null else @bitCast (s .completed_count );
10090 }
10191
10292 fn setIpcFd (s : * Storage , fd : posix.fd_t ) void {
@@ -538,14 +528,9 @@ fn serialize() Serialized {
538528 @memcpy (& dest_storage .name , & storage_ptr .name );
539529 dest_storage .completed_count = @atomicLoad (u32 , & storage_ptr .completed_count , .monotonic );
540530 dest_storage .estimated_total_count = @atomicLoad (u32 , & storage_ptr .estimated_total_count , .monotonic );
541-
542- if (dest_storage .getIpcFd () != null ) {
543- any_ipc = true ;
544- dest_storage .completed_count |= @as (u32 , @intCast (i )) << 16 ;
545- }
546-
547531 const end_parent = @atomicLoad (Node .Parent , parent_ptr , .seq_cst );
548532 if (begin_parent == end_parent ) {
533+ any_ipc = any_ipc or (dest_storage .getIpcFd () != null );
549534 serialized_node_parents_buffer [serialized_len ] = begin_parent ;
550535 serialized_node_map_buffer [i ] = @enumFromInt (serialized_len );
551536 serialized_len += 1 ;
@@ -577,23 +562,25 @@ fn serialize() Serialized {
577562
578563var parents_copy : [default_node_storage_buffer_len ]Node.Parent = undefined ;
579564var storage_copy : [default_node_storage_buffer_len ]Node.Storage = undefined ;
565+ var ipc_metadata_copy : [default_node_storage_buffer_len ]SavedMetadata = undefined ;
580566
581- const SavedMetadata = extern struct {
567+ var ipc_metadata : [default_node_storage_buffer_len ]SavedMetadata = undefined ;
568+ var ipc_metadata_len : u16 = 0 ;
569+
570+ const SavedMetadata = struct {
571+ ipc_fd : u16 ,
572+ main_index : u16 ,
582573 start_index : u16 ,
583574 nodes_len : u16 ,
584- main_index : u16 ,
585- flags : Flags ,
586-
587- const Flags = enum (u16 ) {
588- saved = std .math .maxInt (u16 ),
589- _ ,
590- };
591575};
592576
593577fn serializeIpc (start_serialized_len : usize ) usize {
594578 var serialized_len = start_serialized_len ;
595579 var pipe_buf : [2 * 4096 ]u8 align (4 ) = undefined ;
596580
581+ const old_ipc_metadata = ipc_metadata_copy [0.. ipc_metadata_len ];
582+ ipc_metadata_len = 0 ;
583+
597584 main_loop : for (
598585 serialized_node_parents_buffer [0.. serialized_len ],
599586 serialized_node_storage_buffer [0.. serialized_len ],
@@ -618,23 +605,23 @@ fn serializeIpc(start_serialized_len: usize) usize {
618605 // Ignore all but the last message on the pipe.
619606 var input : []align (2 ) u8 = pipe_buf [0.. bytes_read ];
620607 if (input .len == 0 ) {
621- serialized_len = useSavedIpcData (serialized_len , main_storage , main_index );
608+ serialized_len = useSavedIpcData (serialized_len , main_storage , main_index , old_ipc_metadata );
622609 continue ;
623610 }
624611
625612 const storage , const parents = while (true ) {
626613 if (input .len < 4 ) {
627614 std .log .warn ("short read: {d} out of 4 header bytes" , .{input .len });
628615 // TODO keep track of the short read to trash odd bytes with the next read
629- serialized_len = useSavedIpcData (serialized_len , main_storage , main_index );
616+ serialized_len = useSavedIpcData (serialized_len , main_storage , main_index , old_ipc_metadata );
630617 continue :main_loop ;
631618 }
632619 const subtree_len = std .mem .readInt (u32 , input [0.. 4], .little );
633620 const expected_bytes = 4 + subtree_len * (@sizeOf (Node .Storage ) + @sizeOf (Node .Parent ));
634621 if (input .len < expected_bytes ) {
635622 std .log .warn ("short read: {d} out of {d} ({d} nodes)" , .{ input .len , expected_bytes , subtree_len });
636623 // TODO keep track of the short read to trash odd bytes with the next read
637- serialized_len = useSavedIpcData (serialized_len , main_storage , main_index );
624+ serialized_len = useSavedIpcData (serialized_len , main_storage , main_index , old_ipc_metadata );
638625 continue :main_loop ;
639626 }
640627 if (input .len > expected_bytes ) {
@@ -650,16 +637,16 @@ fn serializeIpc(start_serialized_len: usize) usize {
650637 };
651638
652639 // Remember in case the pipe is empty on next update.
653- const real_storage : * Node.Storage = Node . storageByIndex ( main_storage . getMainStorageIndex ());
654- @as ( * SavedMetadata , @ptrCast ( & real_storage . name )) .* = .{
640+ ipc_metadata [ ipc_metadata_len ] = .{
641+ . ipc_fd = @intCast ( fd ),
655642 .start_index = @intCast (serialized_len ),
656643 .nodes_len = @intCast (parents .len ),
657644 .main_index = @intCast (main_index ),
658- .flags = .saved ,
659645 };
646+ ipc_metadata_len += 1 ;
660647
661648 // Mount the root here.
662- main_storage .* = storage [0 ];
649+ copyRoot ( main_storage , & storage [0 ]) ;
663650
664651 // Copy the rest of the tree to the end.
665652 @memcpy (serialized_node_storage_buffer [serialized_len .. ][0 .. storage .len - 1 ], storage [1.. ]);
@@ -685,34 +672,56 @@ fn serializeIpc(start_serialized_len: usize) usize {
685672 // Save a copy in case any pipes are empty on the next update.
686673 @memcpy (parents_copy [0.. serialized_len ], serialized_node_parents_buffer [0.. serialized_len ]);
687674 @memcpy (storage_copy [0.. serialized_len ], serialized_node_storage_buffer [0.. serialized_len ]);
675+ @memcpy (ipc_metadata_copy [0.. ipc_metadata_len ], ipc_metadata [0.. ipc_metadata_len ]);
688676
689677 return serialized_len ;
690678}
691679
692- fn useSavedIpcData (start_serialized_len : usize , main_storage : * Node.Storage , main_index : usize ) usize {
693- const saved_metadata : * SavedMetadata = @ptrCast (& main_storage .name );
694- if (saved_metadata .flags != .saved ) {
680+ fn copyRoot (dest : * Node.Storage , src : * align (2 ) Node.Storage ) void {
681+ dest .* = .{
682+ .completed_count = src .completed_count ,
683+ .estimated_total_count = src .estimated_total_count ,
684+ .name = if (src .name [0 ] == 0 ) dest .name else src .name ,
685+ };
686+ }
687+
688+ fn findOld (ipc_fd : posix.fd_t , old_metadata : []const SavedMetadata ) ? * const SavedMetadata {
689+ for (old_metadata ) | * m | {
690+ if (m .ipc_fd == ipc_fd )
691+ return m ;
692+ }
693+ return null ;
694+ }
695+
696+ fn useSavedIpcData (
697+ start_serialized_len : usize ,
698+ main_storage : * Node.Storage ,
699+ main_index : usize ,
700+ old_metadata : []const SavedMetadata ,
701+ ) usize {
702+ const ipc_fd = main_storage .getIpcFd ().? ;
703+ const saved_metadata = findOld (ipc_fd , old_metadata ) orelse {
695704 main_storage .completed_count = 0 ;
696705 main_storage .estimated_total_count = 0 ;
697706 return start_serialized_len ;
698- }
707+ };
699708
700709 const start_index = saved_metadata .start_index ;
701710 const nodes_len = saved_metadata .nodes_len ;
702711 const old_main_index = saved_metadata .main_index ;
703712
704- const real_storage : * Node.Storage = Node . storageByIndex ( main_storage . getMainStorageIndex ());
705- @as ( * SavedMetadata , @ptrCast ( & real_storage . name )) .* = .{
713+ ipc_metadata [ ipc_metadata_len ] = .{
714+ . ipc_fd = @intCast ( ipc_fd ),
706715 .start_index = @intCast (start_serialized_len ),
707716 .nodes_len = nodes_len ,
708717 .main_index = @intCast (main_index ),
709- .flags = .saved ,
710718 };
719+ ipc_metadata_len += 1 ;
711720
712721 const parents = parents_copy [start_index .. ][0 .. nodes_len - 1 ];
713722 const storage = storage_copy [start_index .. ][0 .. nodes_len - 1 ];
714723
715- main_storage .* = storage_copy [old_main_index ];
724+ copyRoot ( main_storage , & storage_copy [old_main_index ]) ;
716725
717726 @memcpy (serialized_node_storage_buffer [start_serialized_len .. ][0.. storage .len ], storage );
718727
0 commit comments