public IList <Object> GetObjects(IList <IObjRef> orisToGet, ICacheIntern targetCache, CacheDirective cacheDirective) { CheckNotDisposed(); if (orisToGet == null || orisToGet.Count == 0) { return(new List <Object>(0)); } IEventQueue eventQueue = EventQueue; if (eventQueue != null) { eventQueue.Pause(this); } try { bool oldCacheModificationValue = CacheModification.Active; bool acquireSuccess = AcquireHardRefTLIfNotAlready(orisToGet.Count); CacheModification.Active = true; try { if (cacheDirective.HasFlag(CacheDirective.LoadContainerResult) || cacheDirective.HasFlag(CacheDirective.CacheValueResult)) { return(Parent.GetObjects(orisToGet, this, cacheDirective)); } bool doAnotherRetry; while (true) { doAnotherRetry = false; IList <Object> result = GetObjectsRetry(orisToGet, cacheDirective, out doAnotherRetry); if (!doAnotherRetry) { return(result); } } } finally { CacheModification.Active = oldCacheModificationValue; ClearHardRefs(acquireSuccess); } } finally { if (eventQueue != null) { eventQueue.Resume(this); } } }
protected IList <Object> CreateResult(IList <IObjRef> orisToGet, CacheDirective cacheDirective, bool checkVersion) { List <Object> result = new List <Object>(orisToGet.Count); bool returnMisses = cacheDirective.HasFlag(CacheDirective.ReturnMisses); for (int a = 0, size = orisToGet.Count; a < size; a++) { IObjRef oriToGet = orisToGet[a]; if (oriToGet == null) { if (returnMisses) { result.Add(null); } continue; } if (oriToGet is IDirectObjRef) { IDirectObjRef dori = (IDirectObjRef)oriToGet; Object entity = dori.Direct; if (entity != null) { result.Add(entity); continue; } } IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(oriToGet.RealType); Object cacheValue = GetCacheValue(metaData, oriToGet, checkVersion); if (cacheValue != null || returnMisses) { result.Add(cacheValue); } } return(result); }
protected IList <Object> GetObjectsRetry(IList <IObjRef> orisToGet, CacheDirective cacheDirective, out bool doAnotherRetry) { doAnotherRetry = false; Lock readLock = ReadLock; if (cacheDirective.HasFlag(CacheDirective.FailEarly)) { readLock.Lock(); try { return(CreateResult(orisToGet, cacheDirective, true)); } finally { readLock.Unlock(); } } List <IObjRef> orisToLoad = new List <IObjRef>(); int cacheVersionBeforeLongTimeAction = WaitForConcurrentReadFinish(orisToGet, orisToLoad); if (orisToLoad.Count == 0) { // Everything found in the cache. We STILL hold the readlock so we can immediately create the result // We already even checked the version. So we do not bother version anymore here try { return(CreateResult(orisToGet, cacheDirective, false)); } finally { readLock.Unlock(); } } CacheDirective parentCacheDirective = CacheDirective.None; if (cacheDirective.HasFlag(CacheDirective.FailInCacheHierarchy)) { parentCacheDirective = CacheDirective.FailEarly; } Parent.GetObjects(orisToLoad, this, parentCacheDirective); // Objects do not have to be put, because their were already // added by the parent to this cache readLock.Lock(); try { int cacheVersionAfterLongTimeAction = changeVersion; if (cacheVersionAfterLongTimeAction != cacheVersionBeforeLongTimeAction) { // Another thread did some changes (possibly DataChange-Remove actions) // We have to ensure that our result-scope is still valid // We return null to allow a further full retry of getObjects() doAnotherRetry = true; return(null); } return(CreateResult(orisToGet, cacheDirective, false)); } finally { readLock.Unlock(); } }