예제 #1
0
        //
        //  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);
        }
예제 #2
0
        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);
                    }
                }
            }
        }
예제 #3
0
        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
        }
예제 #4
0
        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
        }
예제 #5
0
        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();
            }
        }