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 }
//message callback protected override void ReceiveCallback(IAsyncResult ar) { base.ReceiveCallback(ar); if (FReceiveSuccess && !(this is UDPTimeClient)) { FInternalServer.Send(BitConverter.GetBytes(ElapsedSeconds), 8, FRemoteSender); } }
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; } }