Esempio n. 1
0
            public Task <IDisposable> EnterAsync(CancellationToken ct)
            {
                // The item may have been already dequeued by the previous since it was set as '_next',
                // If so, return sync (note: the '_count' was already incremented)
                if (_state == State.Waiting)
                {
                    _enterAsync = new FastTaskCompletionSource <IDisposable>();

                    if (ct.CanBeCanceled)
                    {
                        _enterAsync.OnCompleted(ct.Register(Abort).Dispose);

                        void Abort()
                        {
                            if (Interlocked.CompareExchange(ref _state, State.Aborted, State.Waiting) == State.Waiting)
                            {
                                _enterAsync.SetCanceled();
                            }
                        }
                    }

                    // This instance may have been dequeued by previous while we where initiazing the async hanlde,
                    // so make sure to not wait a task that will never complete.
                    if (_state == State.Waiting)
                    {
                        return(_enterAsync.Task);
                    }
                }

                return(Task.FromResult <IDisposable>(new Handle(this)));
            }
Esempio n. 2
0
        private bool DequeueWaiter(out FastTaskCompletionSource <bool> result)
        {
#if HAS_NO_CONCURRENT_DICT
            lock (_queue)
            {
                if (_queue.Count == 0)
                {
                    result = null;
                    return(false);
                }

                result = _queue.Dequeue();
                return(true);
            }
#else
            return(_queue.TryDequeue(out result));
#endif
        }
Esempio n. 3
0
        public Task <bool> Wait(CancellationToken cancellationToken)
        {
            var src = new FastTaskCompletionSource <bool>();

            bool shouldWait;
            int  result;

            do
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    src.TrySetResult(false);
                    return(src.Task);
                }

                shouldWait = true;
                result     = _currentCount;

                if (result > 0)
                {
                    shouldWait = false;
                }
                else
                {
                    break;
                }
            } while (Interlocked.CompareExchange(ref _currentCount, result - 1, result) != result);

            if (!shouldWait)
            {
                src.TrySetResult(true);
            }
            else
            {
#if HAS_NO_CONCURRENT_DICT
                lock (_queue)
#endif
                {
                    _queue.Enqueue(src);
                }
            }

            return(src.Task);
        }