diff --git a/src/CSharpTest.Net.Collections/Collections/NodeCache.Base.cs b/src/CSharpTest.Net.Collections/Collections/NodeCache.Base.cs index 9c6c5e2..ef7d628 100644 --- a/src/CSharpTest.Net.Collections/Collections/NodeCache.Base.cs +++ b/src/CSharpTest.Net.Collections/Collections/NodeCache.Base.cs @@ -89,7 +89,7 @@ public void DeleteAll() public abstract ILockStrategy CreateLock(NodeHandle handle, out object refobj); protected abstract NodePin Lock(NodePin parent, LockType ltype, NodeHandle child); - public NodePin LockRoot(LockType ltype) + public virtual NodePin LockRoot(LockType ltype) { return Lock(null, ltype, RootHandle); } diff --git a/src/CSharpTest.Net.Collections/Collections/NodeCache.Normal.cs b/src/CSharpTest.Net.Collections/Collections/NodeCache.Normal.cs index 9d54e8a..3b9c54f 100644 --- a/src/CSharpTest.Net.Collections/Collections/NodeCache.Normal.cs +++ b/src/CSharpTest.Net.Collections/Collections/NodeCache.Normal.cs @@ -179,6 +179,11 @@ public override ILockStrategy CreateLock(NodeHandle handle, out object refobj) } protected override NodePin Lock(NodePin parent, LockType ltype, NodeHandle child) + { + return LockInternal(parent, ltype, child, false); + } + + private NodePin LockInternal(NodePin parent, LockType ltype, NodeHandle child, bool ignoreHandleComparison) { CacheEntry entry = GetCache(child, false); @@ -200,10 +205,13 @@ protected override NodePin Lock(NodePin parent, LockType ltype, NodeHandle child if (node == null) { InvalidNodeHandleException.Assert( - Storage.TryGetNode(child.StoreHandle, out node, NodeSerializer) - && node != null - && node.StorageHandle.Equals(entry.Handle.StoreHandle) - ); + Storage.TryGetNode(child.StoreHandle, out node, NodeSerializer) && node != null && + ignoreHandleComparison + ? true + : node.StorageHandle.Equals(entry.Handle.StoreHandle)); + + + Node old = Interlocked.CompareExchange(ref entry.Node, node, null); Assert(null == old, "Collision on cache load."); } @@ -246,6 +254,11 @@ public override void UpdateNode(NodePin node) Assert(ReferenceEquals(old, node.Original), "Node was modified without lock"); } } + + public override NodePin LockRoot(LockType ltype) + { + return LockInternal(null, ltype, RootHandle, true); + } } } }