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;
            CacheEntry[]    depEntries = s_entriesEmpty;
            string []       filenames, cachekeys;
            CacheInternal   cacheInternal;

            _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 CacheEntry) {
                            depEntries = new CacheEntry[1] {(CacheEntry) (d_entries)};
                        }
                        else {
                            depEntries = (CacheEntry[]) (d_entries);
                            // verify that the object was fully constructed
                            foreach (CacheEntry 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;
                if (lenMyEntries > 0 && !_bits[CHANGED]) {
                    CacheEntry[] myEntries = new CacheEntry[lenMyEntries];

                    // Monitor entries from the existing cache dependency
                    int i = 0;
                    foreach (CacheEntry entry in depEntries) {
                        entry.AddCacheDependencyNotify(this);
                        myEntries[i++] = entry;
                    }

                    // Monitor new entries specified for this depenedency
                    // Entries must be added to cache, and created before the startTime
                    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.UtcCreated > _utcLastModified) {
                                _utcLastModified = entry.UtcCreated;
                            }

                            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

                                _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();
            }
        }
        void InitForMemoryCache(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart) {
            bool dispose = true;
            try {
                MemCache memCache = HttpRuntime.CacheInternal as MemCache;
                _bits = new SafeBitVector32(0);
                _utcLastModified = DateTime.MinValue;
                IList<String> files = filenamesArg;
                IList<String> keys = cachekeysArg;
                if (dependency != null) {
                    ReadOnlyCollection<string> filePaths = (dependency._fileChangeMonitor != null) ? dependency._fileChangeMonitor.FilePaths : null;
                    ReadOnlyCollection<string> cacheKeys = (dependency._entryChangeMonitor != null) ? dependency._entryChangeMonitor.CacheKeys : null;
                    if (filePaths != null || filenamesArg != null) {
                        if (filePaths == null) {
                            files = filenamesArg;
                        }
                        else if (filenamesArg == null) {
                            files = filePaths;
                        }
                        else {
                            files = new List<String>(filenamesArg.Length + filePaths.Count);
                            foreach (string f in filenamesArg) {
                                files.Add(f);
                            }
                            foreach (string f in filePaths) {
                                files.Add(f);
                            }
                        }
                    }
                    if (cacheKeys != null || cachekeysArg != null) {
                        if (cacheKeys == null) {
                            keys = cachekeysArg;
                        }
                        else if (cachekeysArg == null) {
                            keys = cacheKeys;
                        }
                        else {
                            keys = new List<String>(cachekeysArg.Length + cacheKeys.Count);
                            foreach (string f in cachekeysArg) {
                                keys.Add(f);
                            }
                            foreach (string f in cacheKeys) {
                                keys.Add(f);
                            }
                        }
                    }
                }
                
                _fileChangeMonitor = (files != null) ? new HostFileChangeMonitor(files) : null;
                _entryChangeMonitor = (keys != null) ? memCache.CreateCacheEntryChangeMonitor(keys, isPublic) : null;
                
                string uniqueId = null;
                
                if (_fileChangeMonitor != null) {
                    _utcLastModified = _fileChangeMonitor.LastModified.UtcDateTime;
                    uniqueId = _fileChangeMonitor.UniqueId;
                    _fileChangeMonitor.NotifyOnChanged(new OnChangedCallback(OnChangedCallback));
                }
                if (_entryChangeMonitor != null) {
                    DateTime utcLastModified = _entryChangeMonitor.LastModified.UtcDateTime;
                    if (utcLastModified > _utcLastModified) {
                        _utcLastModified = utcLastModified;
                    }
                    uniqueId += _entryChangeMonitor.UniqueId;
                    _entryChangeMonitor.NotifyOnChanged(new OnChangedCallback(OnChangedCallback));
                }
                
                _uniqueID = uniqueId;
#if DBG
                _isUniqueIDInitialized = true;
#endif
                // check if file has changed since the start time
                if (utcStart < DateTime.MaxValue) {
                    if (_utcLastModified > utcStart
                        && !(_utcLastModified - DateTime.UtcNow > FUTURE_FILETIME_BUFFER)) {   // See VSWhidbey 400917
                        _bits[CHANGED] = true;
                    }
                }

                _bits[BASE_INIT] = true;
                if (dependency != null && dependency._bits[CHANGED]) {
                    _bits[CHANGED] = true;
                }
                if (_bits[WANTS_DISPOSE] || _bits[CHANGED]) {
                    Debug.Trace("CacheDependencyInit", "WANTS_DISPOSE or CHANGED.  InitForMemoryCache calling DisposeInternal");
                    DisposeInternal();
                }
                dispose = false;
            }
            finally {
                if (dispose) {
                    _bits[BASE_INIT] = true;
                    Debug.Trace("CacheDependencyInit", "\n\nERROR in CacheDependency.InitForMemoryCache, calling DisposeInternal");
                    DisposeInternal();
                }
            }
        }
Exemplo n.º 3
0
        void InitForMemoryCache(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart)
        {
            bool dispose = true;

            try {
                MemCache memCache = HttpRuntime.InternalCache as MemCache;
                _bits            = new SafeBitVector32(0);
                _utcLastModified = DateTime.MinValue;
                IList <String> files = filenamesArg;
                IList <String> keys  = cachekeysArg;
                if (dependency != null)
                {
                    ReadOnlyCollection <string> filePaths = (dependency._fileChangeMonitor != null) ? dependency._fileChangeMonitor.FilePaths : null;
                    ReadOnlyCollection <string> cacheKeys = (dependency._entryChangeMonitor != null) ? dependency._entryChangeMonitor.CacheKeys : null;
                    if (filePaths != null || filenamesArg != null)
                    {
                        if (filePaths == null)
                        {
                            files = filenamesArg;
                        }
                        else if (filenamesArg == null)
                        {
                            files = filePaths;
                        }
                        else
                        {
                            files = new List <String>(filenamesArg.Length + filePaths.Count);
                            foreach (string f in filenamesArg)
                            {
                                files.Add(f);
                            }
                            foreach (string f in filePaths)
                            {
                                files.Add(f);
                            }
                        }
                    }
                    if (cacheKeys != null || cachekeysArg != null)
                    {
                        if (cacheKeys == null)
                        {
                            keys = cachekeysArg;
                        }
                        else if (cachekeysArg == null)
                        {
                            keys = cacheKeys;
                        }
                        else
                        {
                            keys = new List <String>(cachekeysArg.Length + cacheKeys.Count);
                            foreach (string f in cachekeysArg)
                            {
                                keys.Add(f);
                            }
                            foreach (string f in cacheKeys)
                            {
                                keys.Add(f);
                            }
                        }
                    }
                }

                _fileChangeMonitor  = (files != null) ? new HostFileChangeMonitor(files) : null;
                _entryChangeMonitor = (keys != null) ? memCache.CreateCacheEntryChangeMonitor(keys, isPublic) : null;

                string uniqueId = null;

                if (_fileChangeMonitor != null)
                {
                    _utcLastModified = _fileChangeMonitor.LastModified.UtcDateTime;
                    uniqueId         = _fileChangeMonitor.UniqueId;
                    _fileChangeMonitor.NotifyOnChanged(new OnChangedCallback(OnChangedCallback));
                }
                if (_entryChangeMonitor != null)
                {
                    DateTime utcLastModified = _entryChangeMonitor.LastModified.UtcDateTime;
                    if (utcLastModified > _utcLastModified)
                    {
                        _utcLastModified = utcLastModified;
                    }
                    uniqueId += _entryChangeMonitor.UniqueId;
                    _entryChangeMonitor.NotifyOnChanged(new OnChangedCallback(OnChangedCallback));
                }

                _uniqueID = uniqueId;
#if DBG
                _isUniqueIDInitialized = true;
#endif
                // check if file has changed since the start time
                if (utcStart < DateTime.MaxValue)
                {
                    if (_utcLastModified > utcStart &&
                        !(_utcLastModified - DateTime.UtcNow > FUTURE_FILETIME_BUFFER))        // See VSWhidbey 400917
                    {
                        _bits[CHANGED] = true;
                    }
                }

                _bits[BASE_INIT] = true;
                if (dependency != null && dependency._bits[CHANGED])
                {
                    _bits[CHANGED] = true;
                }
                if (_bits[WANTS_DISPOSE] || _bits[CHANGED])
                {
                    Debug.Trace("CacheDependencyInit", "WANTS_DISPOSE or CHANGED.  InitForMemoryCache calling DisposeInternal");
                    DisposeInternal();
                }
                dispose = false;
            }
            finally {
                if (dispose)
                {
                    _bits[BASE_INIT] = true;
                    Debug.Trace("CacheDependencyInit", "\n\nERROR in CacheDependency.InitForMemoryCache, calling DisposeInternal");
                    DisposeInternal();
                }
            }
        }
Exemplo n.º 4
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();
            }
        }
 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();
     }
 }