CacheEntry GetCache(NodeHandle handle, bool isNew) { Utils.WeakReference <CacheEntry> weakRef; CacheEntry entry = null; if (!isNew) { if (handle.TryGetCache(out weakRef) && weakRef != null && weakRef.TryGetTarget(out entry)) { return(entry); } using (_cacheLock.Read(base.Options.LockTimeout)) { if (_cache.TryGetValue(handle, out weakRef)) { if (!weakRef.TryGetTarget(out entry)) { using (new SafeLock <DeadlockException>(weakRef)) { if (!weakRef.TryGetTarget(out entry)) { weakRef.Target = entry = new CacheEntry(this, handle); } handle.SetCacheEntry(weakRef); } } } } } if (entry == null) { using (_cacheLock.Write(base.Options.LockTimeout)) { if (!_cache.TryGetValue(handle, out weakRef)) { _cache.Add(handle, weakRef = new Utils.WeakReference <CacheEntry>(entry = new CacheEntry(this, handle))); handle.SetCacheEntry(weakRef); } else { if (!weakRef.TryGetTarget(out entry)) { using (new SafeLock <DeadlockException>(weakRef)) { if (!weakRef.TryGetTarget(out entry)) { weakRef.Target = entry = new CacheEntry(this, handle); } handle.SetCacheEntry(weakRef); } } } } } Assert(entry != null, "Cache entry is null"); _keepAlive.Add(entry); return(entry); }
protected override NodePin Lock(NodePin parent, LockType ltype, NodeHandle child) { ILockStrategy lck; if (!child.TryGetCache(out lck)) { using (_lock.Write(base.Options.LockTimeout)) { if (!_list.TryGetValue(child.StoreHandle, out lck)) { _list.Add(child.StoreHandle, lck = LockFactory.Create()); child.SetCacheEntry(lck); } } } bool success; if (ltype == LockType.Read) { success = lck.TryRead(base.Options.LockTimeout); } else { success = lck.TryWrite(base.Options.LockTimeout); } DeadlockException.Assert(success); try { Node node; success = Storage.TryGetNode(child.StoreHandle, out node, NodeSerializer); Assert(success && node != null); return(new NodePin(child, lck, ltype, ltype, lck, node, null)); } catch { if (ltype == LockType.Read) { lck.ReleaseRead(); } else { lck.ReleaseWrite(); } throw; } }
protected override NodePin Lock(NodePin parent, LockType ltype, NodeHandle child) { NodeWithLock nlck; if (!child.TryGetCache(out nlck)) { child.SetCacheEntry(nlck = new NodeWithLock(null, LockFactory.Create())); } bool acquired; if (ltype == LockType.Read) { acquired = nlck.Lock.TryRead(base.Options.LockTimeout); } else { acquired = nlck.Lock.TryWrite(base.Options.LockTimeout); } DeadlockException.Assert(acquired); try { if (nlck.Node == null) { using (new SafeLock <DeadlockException>(nlck, base.Options.LockTimeout)) Storage.TryGetNode(child.StoreHandle, out nlck.Node, NodeSerializer); } Assert(nlck.Node != null); return(new NodePin(child, nlck.Lock, ltype, ltype, nlck, nlck.Node, null)); } catch { if (ltype == LockType.Read) { nlck.Lock.ReleaseRead(); } else { nlck.Lock.ReleaseWrite(); } throw; } }