/* * Shutdown all dependency monitoring and firing of OnChanged notification. */ internal void DisposeInternal() { if (SetBit(DISPOSED)) { if (_filenames != null) { FileChangesMonitor fmon = HttpRuntime.FileChangesMonitor; string oneFilename = _filenames as string; if (oneFilename != null) { fmon.StopMonitoringPath(oneFilename, this); } else { string[] filenames = (string[])_filenames; foreach (string filename in filenames) { // ensure that we handle partially contructed // objects by checking filename for null if (filename != null) { fmon.StopMonitoringPath(filename, this); } } } } if (_entries != null) { CacheEntry oneEntry = _entries as CacheEntry; if (oneEntry != null) { oneEntry.RemoveCacheDependencyNotify(this); } else { CacheEntry[] entries = (CacheEntry[])_entries; foreach (CacheEntry entry in entries) { // ensure that we handle partially contructed // objects by checking entry for null if (entry != null) { entry.RemoveCacheDependencyNotify(this); } } } } _entryNotify = null; } }
private void DisposeOurself() { object obj2 = this._depFileInfos; object obj3 = this._entries; this._objNotify = null; this._depFileInfos = null; this._entries = null; if (obj2 != null) { FileChangesMonitor fileChangesMonitor = HttpRuntime.FileChangesMonitor; DepFileInfo info = obj2 as DepFileInfo; if (info != null) { fileChangesMonitor.StopMonitoringPath(info._filename, this); } else { DepFileInfo[] infoArray = (DepFileInfo[])obj2; foreach (DepFileInfo info2 in infoArray) { string alias = info2._filename; if (alias != null) { fileChangesMonitor.StopMonitoringPath(alias, this); } } } } if (obj3 != null) { CacheEntry entry = obj3 as CacheEntry; if (entry != null) { entry.RemoveCacheDependencyNotify(this); } else { CacheEntry[] entryArray = (CacheEntry[])obj3; foreach (CacheEntry entry2 in entryArray) { if (entry2 != null) { entry2.RemoveCacheDependencyNotify(this); } } } } }
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(); } }
private void Init(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart) { string[] strArray; string[] strArray2; DepFileInfo[] infoArray = s_depFileInfosEmpty; CacheEntry[] entryArray = s_entriesEmpty; this._bits = new SafeBitVector32(0); if (filenamesArg != null) { strArray = (string[])filenamesArg.Clone(); } else { strArray = null; } if (cachekeysArg != null) { strArray2 = (string[])cachekeysArg.Clone(); } else { strArray2 = null; } this._utcLastModified = DateTime.MinValue; try { if (strArray == null) { strArray = s_stringsEmpty; } else { foreach (string str in strArray) { if (str == null) { throw new ArgumentNullException("filenamesArg"); } if (isPublic) { InternalSecurityPermissions.PathDiscovery(str).Demand(); } } } if (strArray2 == null) { strArray2 = s_stringsEmpty; } else { string[] strArray4 = strArray2; for (int i = 0; i < strArray4.Length; i++) { if (strArray4[i] == null) { throw new ArgumentNullException("cachekeysArg"); } } } if (dependency == null) { dependency = s_dependencyEmpty; } else { if (dependency.GetType() != s_dependencyEmpty.GetType()) { throw new ArgumentException(System.Web.SR.GetString("Invalid_Dependency_Type")); } object obj2 = dependency._depFileInfos; object obj3 = dependency._entries; DateTime time = dependency._utcLastModified; if (dependency._bits[4]) { this._bits[4] = true; this.DisposeInternal(); return; } if (obj2 != null) { if (obj2 is DepFileInfo) { infoArray = new DepFileInfo[] { (DepFileInfo)obj2 }; } else { infoArray = (DepFileInfo[])obj2; } foreach (DepFileInfo info in infoArray) { string path = info._filename; if (path == null) { this._bits[4] = true; this.DisposeInternal(); return; } if (isPublic) { InternalSecurityPermissions.PathDiscovery(path).Demand(); } } } if (obj3 != null) { if (obj3 is CacheEntry) { entryArray = new CacheEntry[] { (CacheEntry)obj3 }; } else { entryArray = (CacheEntry[])obj3; CacheEntry[] entryArray4 = entryArray; for (int j = 0; j < entryArray4.Length; j++) { if (entryArray4[j] == null) { this._bits[4] = true; this.DisposeInternal(); return; } } } } this._utcLastModified = time; } int num = infoArray.Length + strArray.Length; if (num > 0) { int num2; DepFileInfo[] infoArray2 = new DepFileInfo[num]; FileChangeEventHandler callback = new FileChangeEventHandler(this.FileChange); FileChangesMonitor fileChangesMonitor = HttpRuntime.FileChangesMonitor; for (num2 = 0; num2 < num; num2++) { infoArray2[num2] = new DepFileInfo(); } num2 = 0; foreach (DepFileInfo info2 in infoArray) { string alias = info2._filename; fileChangesMonitor.StartMonitoringPath(alias, callback, out infoArray2[num2]._fad); infoArray2[num2]._filename = alias; num2++; } DateTime minValue = DateTime.MinValue; foreach (string str5 in strArray) { DateTime time3 = fileChangesMonitor.StartMonitoringPath(str5, callback, out infoArray2[num2]._fad); infoArray2[num2]._filename = str5; num2++; if (time3 > this._utcLastModified) { this._utcLastModified = time3; } if (utcStart < DateTime.MaxValue) { if (minValue == DateTime.MinValue) { minValue = DateTime.UtcNow; } if ((time3 >= utcStart) && ((time3 - minValue) <= FUTURE_FILETIME_BUFFER)) { this._bits[4] = true; break; } } } if (infoArray2.Length == 1) { this._depFileInfos = infoArray2[0]; } else { this._depFileInfos = infoArray2; } } int num3 = entryArray.Length + strArray2.Length; if ((num3 > 0) && !this._bits[4]) { CacheEntry[] entryArray2 = new CacheEntry[num3]; int num4 = 0; foreach (CacheEntry entry2 in entryArray) { entry2.AddCacheDependencyNotify(this); entryArray2[num4++] = entry2; } CacheInternal cacheInternal = HttpRuntime.CacheInternal; foreach (string str6 in strArray2) { CacheEntry entry3 = (CacheEntry)cacheInternal.DoGet(isPublic, str6, CacheGetOptions.ReturnCacheEntry); if (entry3 != null) { entry3.AddCacheDependencyNotify(this); entryArray2[num4++] = entry3; if (entry3.UtcCreated > this._utcLastModified) { this._utcLastModified = entry3.UtcCreated; } if ((entry3.State == CacheEntry.EntryState.AddedToCache) && (entry3.UtcCreated <= utcStart)) { continue; } this._bits[4] = true; } else { this._bits[4] = true; } break; } if (entryArray2.Length == 1) { this._entries = entryArray2[0]; } else { this._entries = entryArray2; } } this._bits[1] = true; if (dependency._bits[4]) { this._bits[4] = true; } if (this._bits[0x10] || this._bits[4]) { this.DisposeInternal(); } } catch { this._bits[1] = true; this.DisposeInternal(); throw; } finally { this.InitUniqueID(); } }
void Init(bool isPublic, bool isSensitive, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart) { string[] depFilenames = s_stringsEmpty; CacheEntry[] depEntries = s_entriesEmpty; string [] filenames, cachekeys; CacheInternal cacheInternal; Debug.Assert(_bits == 0, "_bits == 0"); if (isSensitive) { _bits = SENSITIVE; } if (filenamesArg != null) { filenames = (string [])filenamesArg.Clone(); } else { filenames = null; } if (cachekeysArg != null) { cachekeys = (string [])cachekeysArg.Clone(); } else { cachekeys = null; } _utcInitTime = DateTime.UtcNow; try { if (filenames != null) { foreach (string f in filenames) { if (f == null) { throw new ArgumentNullException("filenames"); } if (isPublic) { InternalSecurityPermissions.PathDiscovery(f).Demand(); } } } else { filenames = s_stringsEmpty; } if (cachekeys != null) { foreach (string k in cachekeys) { if (k == null) { throw new ArgumentNullException("cachekeys"); } } } else { cachekeys = s_stringsEmpty; } if (dependency != null) { if ((dependency._bits & CHANGED) != 0) { SetBit(CHANGED); return; } if (dependency._filenames != null) { if (dependency._filenames is string) { depFilenames = new string[1] { (string)dependency._filenames }; } else { depFilenames = (string[])(dependency._filenames); } } if (dependency._entries != null) { if (dependency._entries is CacheEntry) { depEntries = new CacheEntry[1] { (CacheEntry)(dependency._entries) }; } else { depEntries = (CacheEntry[])(dependency._entries); } } } else { dependency = s_dependencyEmpty; } int lenMyFilenames = depFilenames.Length + filenames.Length; if (lenMyFilenames > 0) { string[] myFilenames = new string[lenMyFilenames]; FileChangeEventHandler handler = new FileChangeEventHandler(this.FileChange); FileChangesMonitor fmon = HttpRuntime.FileChangesMonitor; int i = 0; foreach (string f in depFilenames) { fmon.StartMonitoringPath(f, handler); myFilenames[i++] = f; } foreach (string f in filenames) { DateTime utcLastWrite = fmon.StartMonitoringPath(f, handler); myFilenames[i++] = f; if (utcStart < DateTime.MaxValue) { Debug.Trace("CacheDependencyInit", "file=" + f + "; utcStart=" + utcStart + "; utcLastWrite=" + utcLastWrite); if (utcLastWrite >= utcStart) { Debug.Trace("CacheDependencyInit", "changes occurred since start time for file " + f); SetBit(CHANGED); break; } } } if (myFilenames.Length == 1) { _filenames = myFilenames[0]; } else { _filenames = myFilenames; } } int lenMyEntries = depEntries.Length + cachekeys.Length; if (lenMyEntries > 0 && (_bits & CHANGED) == 0) { CacheEntry[] myEntries = new CacheEntry[lenMyEntries]; int i = 0; foreach (CacheEntry entry in depEntries) { entry.AddCacheDependencyNotify(this); myEntries[i++] = entry; } cacheInternal = HttpRuntime.CacheInternal; foreach (string k in cachekeys) { CacheEntry entry = (CacheEntry)cacheInternal.DoGet(isPublic, k, CacheGetOptions.ReturnCacheEntry); if (entry != null) { entry.AddCacheDependencyNotify(this); myEntries[i++] = entry; if (entry.State != CacheEntry.EntryState.AddedToCache || entry.UtcCreated > utcStart) { #if DBG if (entry.State != CacheEntry.EntryState.AddedToCache) { Debug.Trace("CacheDependencyInit", "Entry is not in cache, considered changed:" + k); } else { Debug.Trace("CacheDependencyInit", "Changes occurred to entry since start time:" + k); } #endif SetBit(CHANGED); break; } } else { Debug.Trace("CacheDependencyInit", "Cache item not found to create dependency on:" + k); SetBit(CHANGED); break; } } if (myEntries.Length == 1) { _entries = myEntries[0]; } else { _entries = myEntries; } } SetBit(READY); if ((_bits & CHANGED) != 0 || (dependency._bits & CHANGED) != 0) { SetBit(CHANGED); DisposeInternal(); } } catch { DisposeInternal(); throw; } }
internal void OnConfigFileChanged(Object sender, FileChangeEvent e) { string message = FileChangesMonitor.GenerateErrorMessage(e.Action, e.FileName); HttpRuntime.OnConfigChange(message); }