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 }
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); }
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; } }