@@ -49,8 +49,6 @@ pub(crate) mod primitives;
4949use crate :: linear:: OffsetReader ;
5050use crate :: logger:: trace;
5151use crate :: node:: branch:: ReadSerializable as _;
52- use arc_swap:: ArcSwap ;
53- use arc_swap:: access:: DynAccess ;
5452use smallvec:: SmallVec ;
5553use std:: fmt:: Debug ;
5654use std:: io:: { Error , ErrorKind , Read } ;
@@ -236,17 +234,7 @@ impl<S> NodeStore<Arc<ImmutableProposal>, S> {
236234 /// When an immutable proposal commits, we need to reparent any proposal that
237235 /// has the committed proposal as it's parent
238236 pub fn commit_reparent ( & self , other : & NodeStore < Arc < ImmutableProposal > , S > ) {
239- match * other. kind . parent . load ( ) {
240- NodeStoreParent :: Proposed ( ref parent) => {
241- if Arc :: ptr_eq ( & self . kind , parent) {
242- other
243- . kind
244- . parent
245- . store ( NodeStoreParent :: Committed ( self . kind . root_hash ( ) ) . into ( ) ) ;
246- }
247- }
248- NodeStoreParent :: Committed ( _) => { }
249- }
237+ other. kind . commit_reparent ( & self . kind ) ;
250238 }
251239}
252240
@@ -469,7 +457,7 @@ pub struct ImmutableProposal {
469457 /// Nodes that have been deleted in this proposal.
470458 deleted : Box < [ MaybePersistedNode ] > ,
471459 /// The parent of this proposal.
472- parent : Arc < ArcSwap < NodeStoreParent > > ,
460+ parent : Arc < std :: sync :: Mutex < NodeStoreParent > > ,
473461 /// The root of the trie in this proposal.
474462 root : Option < Child > ,
475463}
@@ -478,15 +466,20 @@ impl ImmutableProposal {
478466 /// Returns true if the parent of this proposal is committed and has the given hash.
479467 #[ must_use]
480468 fn parent_hash_is ( & self , hash : Option < TrieHash > ) -> bool {
481- match <Arc < ArcSwap < NodeStoreParent > > as arc_swap:: access:: DynAccess < Arc < _ > > >:: load (
482- & self . parent ,
483- )
484- . as_ref ( )
485- {
469+ match & * self . parent . lock ( ) . expect ( "poisoned lock" ) {
486470 NodeStoreParent :: Committed ( root_hash) => * root_hash == hash,
487471 NodeStoreParent :: Proposed ( _) => false ,
488472 }
489473 }
474+
475+ fn commit_reparent ( self : & Arc < Self > , committing : & Arc < Self > ) {
476+ let mut guard = self . parent . lock ( ) . expect ( "poisoned lock" ) ;
477+ if let NodeStoreParent :: Proposed ( ref parent) = * guard
478+ && Arc :: ptr_eq ( parent, committing)
479+ {
480+ * guard = NodeStoreParent :: Committed ( committing. root_hash ( ) ) ;
481+ }
482+ }
490483}
491484
492485/// Contains the state of a revision of a merkle trie.
@@ -605,7 +598,7 @@ impl<S: ReadableStorage> TryFrom<NodeStore<MutableProposal, S>>
605598 header,
606599 kind : Arc :: new ( ImmutableProposal {
607600 deleted : kind. deleted . into ( ) ,
608- parent : Arc :: new ( ArcSwap :: new ( Arc :: new ( kind. parent ) ) ) ,
601+ parent : Arc :: new ( std :: sync :: Mutex :: new ( kind. parent ) ) ,
609602 root : None ,
610603 } ) ,
611604 storage,
@@ -874,7 +867,6 @@ mod tests {
874867
875868 use crate :: LeafNode ;
876869 use crate :: linear:: memory:: MemStore ;
877- use arc_swap:: access:: DynGuard ;
878870
879871 use super :: * ;
880872 use primitives:: area_size_iter;
@@ -923,21 +915,25 @@ mod tests {
923915 // create an empty r1, check that it's parent is the empty committed version
924916 let r1 = NodeStore :: new ( & base) . unwrap ( ) ;
925917 let r1: NodeStore < Arc < ImmutableProposal > , _ > = r1. try_into ( ) . unwrap ( ) ;
926- let parent: DynGuard < Arc < NodeStoreParent > > = r1. kind . parent . load ( ) ;
927- assert ! ( matches!( * * parent, NodeStoreParent :: Committed ( None ) ) ) ;
918+ {
919+ let parent = r1. kind . parent . lock ( ) . expect ( "poisoned lock" ) ;
920+ assert ! ( matches!( * parent, NodeStoreParent :: Committed ( None ) ) ) ;
921+ }
928922
929923 // create an empty r2, check that it's parent is the proposed version r1
930924 let r2: NodeStore < MutableProposal , _ > = NodeStore :: new ( & r1) . unwrap ( ) ;
931925 let r2: NodeStore < Arc < ImmutableProposal > , _ > = r2. try_into ( ) . unwrap ( ) ;
932- let parent: DynGuard < Arc < NodeStoreParent > > = r2. kind . parent . load ( ) ;
933- assert ! ( matches!( * * parent, NodeStoreParent :: Proposed ( _) ) ) ;
926+ {
927+ let parent = r2. kind . parent . lock ( ) . expect ( "poisoned lock" ) ;
928+ assert ! ( matches!( * parent, NodeStoreParent :: Proposed ( _) ) ) ;
929+ }
934930
935931 // reparent r2
936932 r1. commit_reparent ( & r2) ;
937933
938934 // now check r2's parent, should match the hash of r1 (which is still None)
939- let parent: DynGuard < Arc < NodeStoreParent > > = r2. kind . parent . load ( ) ;
940- if let NodeStoreParent :: Committed ( hash) = & * * parent {
935+ let parent = r2. kind . parent . lock ( ) . expect ( "poisoned lock" ) ;
936+ if let NodeStoreParent :: Committed ( hash) = & * parent {
941937 assert_eq ! ( * hash, r1. root_hash( ) ) ;
942938 assert_eq ! ( * hash, None ) ;
943939 } else {
0 commit comments