Beispiel #1
0
            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;
                }
            }
Beispiel #3
0
            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;
                }
            }