예제 #1
0
        protected internal void SetCacheTimeStamp(IServerProcess process, long clientCacheTimeStamp)
        {
                        #if LOGCACHEEVENTS
            FInternalServer.LogMessage(LogEntryType.Information, String.Format("Thread {0} updating cache time stamp to {1}", Thread.CurrentThread.GetHashCode(), AClientCacheTimeStamp.ToString()));
                        #endif

                        #if USESPINLOCK
            while (Interlocked.CompareExchange(ref _cacheSyncRoot, 1, 0) == 1)
            {
                Thread.SpinWait(100);
            }
            try
                        #else
            lock (FCacheSyncRoot)
                        #endif
            {
                _clientCacheTimeStamp = clientCacheTimeStamp;

                ManualResetEvent signal;
                if (_cacheSignals.TryGetValue(clientCacheTimeStamp, out signal))
                {
                    signal.Set();
                }
            }
                        #if USESPINLOCK
            finally
            {
                Interlocked.Decrement(ref _cacheSyncRoot);
            }
                        #endif
        }
예제 #2
0
        public string[] GetRequiredObjects(RemoteServerSession session, Schema.Catalog catalog, long cacheTimeStamp, out long clientCacheTimeStamp)
        {
            List <string> requiredObjects = new List <string>();
            CatalogCache  cache           = (CatalogCache)_caches[session.CatalogCacheName];

            lock (cache)
            {
                bool cacheChanged = cache.EnsureConsistent(cacheTimeStamp, _defaultCachedObjects);
                foreach (Schema.Object objectValue in catalog)
                {
                    if (!cache.CachedObjects.ContainsName(objectValue.Name))
                    {
                        if (!((objectValue is Schema.DerivedTableVar) && (objectValue.Name == ((Schema.DerivedTableVar)objectValue).SessionObjectName)))
                        {
                            cache.CachedObjects.Add(objectValue);
                        }
                        requiredObjects.Add(objectValue.Name);
                    }
                }

                if (!cacheChanged)
                {
                    cache.UpdateTimeStamp();
                }

                clientCacheTimeStamp = cache.TimeStamp;
            }

            string[] result = new string[requiredObjects.Count];
            requiredObjects.CopyTo(result, 0);

                        #if LOGCACHEEVENTS
            ASession.Server.LogMessage(String.Format("Session {0} cache timestamp updated to {1} with required objects: {2}", ASession.SessionID.ToString(), AClientCacheTimeStamp.ToString(), ExceptionUtility.StringsToCommaList(requiredObjects)));
                        #endif

            return(result);
        }
예제 #3
0
        protected internal void WaitForCacheTimeStamp(IServerProcess process, long clientCacheTimeStamp)
        {
                        #if LOGCACHEEVENTS
            FInternalServer.LogMessage(LogEntryType.Information, String.Format("Thread {0} checking for cache time stamp {1}", Thread.CurrentThread.GetHashCode(), AClientCacheTimeStamp.ToString()));
                        #endif
            try
            {
                ManualResetEvent signal      = null;
                bool             signalAdded = false;

                                #if USESPINLOCK
                while (Interlocked.CompareExchange(ref _cacheSyncRoot, 1, 0) == 1)
                {
                    Thread.SpinWait(100);                      // Prevents CPU starvation
                }
                try
                                #else
                lock (FCacheSyncRoot)
                                #endif
                {
                    if (_clientCacheTimeStamp == clientCacheTimeStamp)
                    {
                        return;
                    }

                    if (_clientCacheTimeStamp > clientCacheTimeStamp)
                    {
                        process.Execute(".System.UpdateTimeStamps();", null);
                        throw new ServerException(ServerException.Codes.CacheSerializationError, clientCacheTimeStamp, _clientCacheTimeStamp);
                    }

                    signalAdded = !_cacheSignals.TryGetValue(clientCacheTimeStamp, out signal);
                    if (signalAdded)
                    {
                        signal = _cacheSignalPool.Acquire();
                        _cacheSignals.Add(clientCacheTimeStamp, signal);
                    }

                    //Error.AssertFail(FCacheSyncEvent.Reset(), "Internal error: CacheSyncEvent reset failed");
                }
                                #if USESPINLOCK
                finally
                {
                    Interlocked.Decrement(ref _cacheSyncRoot);
                }
                                #endif

                                #if LOGCACHEEVENTS
                FInternalServer.LogMessage(LogEntryType.Information, String.Format("Thread {0} waiting for cache time stamp {1}", Thread.CurrentThread.GetHashCode(), AClientCacheTimeStamp.ToString()));
                                #endif

                try
                {
                    if (!(signal.WaitOne(CacheSerializationTimeout)))
                    {
                        throw new ServerException(ServerException.Codes.CacheSerializationTimeout);
                    }
                }
                finally
                {
                    if (signalAdded)
                    {
                                                #if USESPINLOCK
                        while (Interlocked.CompareExchange(ref _cacheSyncRoot, 1, 0) == 1)
                        {
                            Thread.SpinWait(100);                             // Prevents CPU starvation
                        }
                        try
                                                #else
                        lock (FCacheSyncRoot)
                                                #endif
                        {
                            _cacheSignals.Remove(clientCacheTimeStamp);
                        }
                                                #if USESPINLOCK
                        finally
                        {
                            Interlocked.Decrement(ref _cacheSyncRoot);
                        }
                                                #endif

                        _cacheSignalPool.Relinquish(signal);
                    }
                }
            }
            catch (Exception E)
            {
                _internalServer.LogError(E);
                throw E;
            }
        }