Beispiel #1
0
        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();
                }
            }
        }
Beispiel #2
0
        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;
                }
            }
        }