// // This will examine the dependency and determine if it's ONLY a file dependency or not // internal virtual bool IsFileDependency() { #if USE_MEMORY_CACHE if (CacheInternal.UseMemoryCache) { if (_entryChangeMonitor != null) { return(false); } if (_fileChangeMonitor != null) { return(true); } return(false); } #endif object depInfos, l_entries; // Check and see if we are dependent on any cache entries l_entries = _entries; if (l_entries != null) { DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { return(false); } else { DepCacheInfo[] entries = (DepCacheInfo[])l_entries; if (entries != null && entries.Length > 0) { return(false); } } } depInfos = _depFileInfos; if (depInfos != null) { DepFileInfo oneDepFileInfo = depInfos as DepFileInfo; if (oneDepFileInfo != null) { return(true); } else { DepFileInfo[] depFileInfos = (DepFileInfo[])depInfos; if (depFileInfos != null && depFileInfos.Length > 0) { return(true); } } } return(false); }
public void KeepDependenciesAlive() { if (_entries != null) { // update the last access time of every cache item that depends on this dependency DepCacheInfo oneEntry = _entries as DepCacheInfo; if (oneEntry != null) { oneEntry._cacheStore.Get(oneEntry._key); return; } foreach (DepCacheInfo entry in (DepCacheInfo[])_entries) { if (entry != null) { object item = entry._cacheStore.Get(entry._key); } } } }
void InitUniqueID() { StringBuilder sb = null; object l_depFileInfos, l_entries; #if !FEATURE_PAL // no File Change Monitoring // get unique id from files l_depFileInfos = _depFileInfos; if (l_depFileInfos != null) { DepFileInfo oneDepFileInfo = l_depFileInfos as DepFileInfo; if (oneDepFileInfo != null) { sb = new StringBuilder(); AppendFileUniqueId(oneDepFileInfo, sb); } else { DepFileInfo[] depFileInfos = (DepFileInfo[])l_depFileInfos; foreach (DepFileInfo depFileInfo in depFileInfos) { // ensure that we handle partially contructed // objects by checking filename for null if (depFileInfo._filename != null) { if (sb == null) { sb = new StringBuilder(); } AppendFileUniqueId(depFileInfo, sb); } } } } #endif // !FEATURE_PAL // get unique id from cache entries l_entries = _entries; if (l_entries != null) { DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { if (sb == null) { sb = new StringBuilder(); } sb.Append(oneEntry._key); sb.Append(oneEntry.GetHashCode().ToString(CultureInfo.InvariantCulture)); } else { DepCacheInfo[] entries = (DepCacheInfo[])l_entries; foreach (DepCacheInfo entry in entries) { // ensure that we handle partially contructed // objects by checking entry for null if (entry != null) { if (sb == null) { sb = new StringBuilder(); } sb.Append(entry._key); sb.Append(entry.GetHashCode().ToString(CultureInfo.InvariantCulture)); } } } } if (sb != null) { _uniqueID = sb.ToString(); } #if DBG _isUniqueIDInitialized = true; #endif }
void DisposeOurself() { // guarantee that we execute only once if an exception // is thrown from this function by nulling fields before // we access them object l_depFileInfos = _depFileInfos; object l_entries = _entries; _objNotify = null; _depFileInfos = null; _entries = null; // stop monitoring files if (l_depFileInfos != null) { FileChangesMonitor fmon = HttpRuntime.FileChangesMonitor; DepFileInfo oneDepFileInfo = l_depFileInfos as DepFileInfo; if (oneDepFileInfo != null) { fmon.StopMonitoringPath(oneDepFileInfo._filename, this); } else { DepFileInfo[] depFileInfos = (DepFileInfo[])l_depFileInfos; foreach (DepFileInfo depFileInfo in depFileInfos) { // ensure that we handle partially contructed // objects by checking filename for null string filename = depFileInfo._filename; if (filename != null) { fmon.StopMonitoringPath(filename, this); } } } } // stop monitoring cache items if (l_entries != null) { DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { oneEntry._cacheStore.RemoveDependent(oneEntry._key, this); } else { DepCacheInfo[] entries = (DepCacheInfo[])l_entries; foreach (DepCacheInfo entry in entries) { // ensure that we handle partially contructed // objects by checking entry for null if (entry != null) { entry._cacheStore.RemoveDependent(entry._key, this); } } } } #if USE_MEMORY_CACHE if (_fileChangeMonitor != null) { _fileChangeMonitor.Dispose(); } if (_entryChangeMonitor != null) { _entryChangeMonitor.Dispose(); } #endif }
void Init(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart) { #if USE_MEMORY_CACHE if (CacheInternal.UseMemoryCache) { InitForMemoryCache(isPublic, filenamesArg, cachekeysArg, dependency, utcStart); return; } #endif DepFileInfo[] depFileInfos = s_depFileInfosEmpty; DepCacheInfo[] depEntries = s_entriesEmpty; string [] filenames, cachekeys; CacheStoreProvider cache; _bits = new SafeBitVector32(0); // copy array argument contents so they can't be changed beneath us if (filenamesArg != null) { filenames = (string [])filenamesArg.Clone(); } else { filenames = null; } if (cachekeysArg != null) { cachekeys = (string [])cachekeysArg.Clone(); } else { cachekeys = null; } _utcLastModified = DateTime.MinValue; try { // validate filenames array if (filenames == null) { filenames = s_stringsEmpty; } else { foreach (string f in filenames) { if (f == null) { throw new ArgumentNullException("filenamesArg"); } // demand PathDiscovery if public if (isPublic) { InternalSecurityPermissions.PathDiscovery(f).Demand(); } } } if (cachekeys == null) { cachekeys = s_stringsEmpty; } else { // validate cachekeys array foreach (string k in cachekeys) { if (k == null) { throw new ArgumentNullException("cachekeysArg"); } } } // copy all parts of another dependency if provided if (dependency == null) { dependency = s_dependencyEmpty; } else { if (dependency.GetType() != s_dependencyEmpty.GetType()) { throw new ArgumentException(SR.GetString(SR.Invalid_Dependency_Type)); } // Copy the parts of the dependency we need before // we reference them, as the dependency can change // underneath us. object d_depFileInfos = dependency._depFileInfos; object d_entries = dependency._entries; DateTime d_lastModified = dependency._utcLastModified; // if the dependency we're copying has changed, we're done if (dependency._bits[CHANGED]) { _bits[CHANGED] = true; // There is nothing to dispose because we haven't started // monitoring anything yet. But we call DisposeInternal in // order to set the WANTS_DISPOSE bit. DisposeInternal(); return; } // copy depFileInfos if (d_depFileInfos != null) { if (d_depFileInfos is DepFileInfo) { depFileInfos = new DepFileInfo[1] { (DepFileInfo)d_depFileInfos }; } else { depFileInfos = (DepFileInfo[])(d_depFileInfos); } // verify that the object was fully constructed // and that we have permission to discover the file foreach (DepFileInfo depFileInfo in depFileInfos) { string f = depFileInfo._filename; if (f == null) { _bits[CHANGED] = true; // There is nothing to dispose because we haven't started // monitoring anything yet. But we call DisposeInternal in // order to set the WANTS_DISPOSE bit. DisposeInternal(); return; } // demand PathDiscovery if public if (isPublic) { InternalSecurityPermissions.PathDiscovery(f).Demand(); } } } // copy cache entries if (d_entries != null) { if (d_entries is DepCacheInfo) { depEntries = new DepCacheInfo[1] { (DepCacheInfo)(d_entries) }; } else { depEntries = (DepCacheInfo[])(d_entries); // verify that the object was fully constructed foreach (DepCacheInfo entry in depEntries) { if (entry == null) { _bits[CHANGED] = true; // There is nothing to dispose because we haven't started // monitoring anything yet. But we call DisposeInternal in // order to set the WANTS_DISPOSE bit. DisposeInternal(); return; } } } } _utcLastModified = d_lastModified; } // Monitor files for changes int lenMyDepFileInfos = depFileInfos.Length + filenames.Length; if (lenMyDepFileInfos > 0) { DepFileInfo[] myDepFileInfos = new DepFileInfo[lenMyDepFileInfos]; FileChangeEventHandler handler = new FileChangeEventHandler(this.FileChange); FileChangesMonitor fmon = HttpRuntime.FileChangesMonitor; int i; for (i = 0; i < lenMyDepFileInfos; i++) { myDepFileInfos[i] = new DepFileInfo(); } // monitor files from the existing dependency // note that we don't check for start times in the existing dependency i = 0; foreach (DepFileInfo depFileInfo in depFileInfos) { string f = depFileInfo._filename; fmon.StartMonitoringPath(f, handler, out myDepFileInfos[i]._fad); myDepFileInfos[i]._filename = f; i++; } // monitor new files DateTime utcNow = DateTime.MinValue; foreach (string f in filenames) { DateTime utcLastWrite = fmon.StartMonitoringPath(f, handler, out myDepFileInfos[i]._fad); myDepFileInfos[i]._filename = f; i++; if (utcLastWrite > _utcLastModified) { _utcLastModified = utcLastWrite; } // check if file has changed since the start time if (utcStart < DateTime.MaxValue) { if (utcNow == DateTime.MinValue) { utcNow = DateTime.UtcNow; } Debug.Trace("CacheDependencyInit", "file=" + f + "; utcStart=" + utcStart + "; utcLastWrite=" + utcLastWrite); if (utcLastWrite >= utcStart && !(utcLastWrite - utcNow > FUTURE_FILETIME_BUFFER)) // See VSWhidbey 400917 { Debug.Trace("CacheDependencyInit", "changes occurred since start time for file " + f); _bits[CHANGED] = true; break; } } } if (myDepFileInfos.Length == 1) { _depFileInfos = myDepFileInfos[0]; } else { _depFileInfos = myDepFileInfos; } } // Monitor other cache entries for changes int lenMyEntries = depEntries.Length + cachekeys.Length; DateTime lastUpdated; if (lenMyEntries > 0 && !_bits[CHANGED]) { DepCacheInfo[] myEntries = new DepCacheInfo[lenMyEntries]; // Monitor entries from the existing cache dependency int i = 0; foreach (DepCacheInfo entry in depEntries) { entry._cacheStore.AddDependent(entry._key, this, out lastUpdated); myEntries[i++] = entry; } // Monitor new entries specified for this depenedency // Entries must be added to cache, and created before the startTime cache = isPublic ? HttpRuntime.Cache.ObjectCache : HttpRuntime.Cache.InternalCache; foreach (string k in cachekeys) { if (cache.AddDependent(k, this, out lastUpdated)) { myEntries[i++] = new DepCacheInfo() { _cacheStore = cache, _key = k }; if (lastUpdated > _utcLastModified) { _utcLastModified = lastUpdated; } if (lastUpdated > utcStart) // Cache item has been updated since start, consider changed { #if DBG Debug.Trace("CacheDependencyInit", "Changes occurred to entry since start time:" + k); #endif _bits[CHANGED] = true; break; } } else { Debug.Trace("CacheDependencyInit", "Cache item not found to create dependency on:" + k); _bits[CHANGED] = true; break; } } if (myEntries.Length == 1) { _entries = myEntries[0]; } else { _entries = myEntries; } } _bits[BASE_INIT] = true; if (dependency._bits[CHANGED]) { _bits[CHANGED] = true; } if (_bits[WANTS_DISPOSE] || _bits[CHANGED]) { DisposeInternal(); } Debug.Assert(_objNotify == null, "_objNotify == null"); } catch { // derived constructor will not execute due to the throw, // so we just force a dispose on ourselves _bits[BASE_INIT] = true; DisposeInternal(); throw; } finally { InitUniqueID(); } }