private void clearTimedOutRequests(object state) { lock (this.waitingTasks) { while (this.timeoutTasks.Count > 0) { SyncTask sTask = this.timeoutTasks.Max; Thread.BeginCriticalRegion(); if (sTask.TimeoutMomentUtc <= DateTime.UtcNow) { this.timeoutTasks.Remove(sTask); this.waitingTasks.RemoveO1(sTask); this.syncTaskLookup.Remove(sTask.ReceiptTask); sTask.TrySignalSource(SyncTask.SourceStates.False); sTask.Dispose(); } else { int delay = Math.Max(0, (int)Math.Ceiling((sTask.TimeoutMomentUtc - DateTime.UtcNow).TotalMilliseconds)); this.timer.Change(delay, Timeout.Infinite); break; } Thread.EndCriticalRegion(); } } }
private Task <bool> enterGeneralized(ref Task <bool> receipt, int timeout, CancellationToken cancellationToken) { if (timeout != Timeout.Infinite && timeout < 0) { throw new ArgumentException("Timeout should be either nonnegative or Timeout.Infinite.", "timeout"); } Contract.EndContractBlock(); if (cancellationToken.IsCancellationRequested) { return(new Task <bool>(returnFalse, cancellationToken)); } DateTime timeoutMomentUtc = timeout > 0 ? DateTime.UtcNow.AddMilliseconds(timeout) : default(DateTime); lock (this.waitingTasks) { try { SpinWait spinWait = new SpinWait(); while (Interlocked.CompareExchange(ref this.queueCount, 1, 0) < 0) { spinWait.SpinOnce(); } if (this.waitingTasks.Count == 0) { Task <bool> ret = this.reusesReceipts ? stockTrueResult : Task <bool> .FromResult(true); bool returnNow = false; try { } finally { if (Interlocked.CompareExchange(ref this.lockHeldBy, ret, null) == null) { receipt = ret; returnNow = true; } } if (returnNow) { return(receipt); } } TaskCompletionSource <bool> src = new TaskCompletionSource <bool>(); SyncTask sTask = timeout > 0 ? new SyncTask(src, cancellationToken, timeoutMomentUtc, this) : new SyncTask(src, cancellationToken, this); try { } finally { if (timeout > 0) { if (timeoutMomentUtc < DateTime.UtcNow) { sTask.TrySignalSource(SyncTask.SourceStates.False); } else { this.waitingTasks.Enqueue(sTask); this.syncTaskLookup[sTask.ReceiptTask] = sTask; if (this.timeoutTasks == null) { this.initializeTimeoutManager(); } if (this.timeoutTasks.Count == 0 || sTask.CompareTo(this.timeoutTasks.Max) > 0) { this.timeoutTasks.Add(sTask); int delay = Math.Max(0, (int)Math.Ceiling((timeoutMomentUtc - DateTime.UtcNow).TotalMilliseconds)); this.timer.Change(delay, Timeout.Infinite); } else { this.timeoutTasks.Add(sTask); } } } else if (timeout == Timeout.Infinite) { this.waitingTasks.Enqueue(sTask); this.syncTaskLookup[sTask.ReceiptTask] = sTask; } receipt = src.Task; } return(receipt); } finally { this.queueCount = this.waitingTasks.Count; } } }