Beispiel #1
0
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) // TODO: Test coverage?
        {
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }
            if (millisecondsTimeout == -1)
            {
                return(WaitAsync(cancellationToken).ContinueWith(_ => true));
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            CheckDisposed();
            var source = new TaskCompletionSource <bool>();

            if (Wait(0, cancellationToken))
            {
                source.SetResult(true);
                return(source.Task);
            }
            Thread.MemoryBarrier();
            Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken);
            cancellationToken.Register(() => source.SetCanceled());
            _asyncWaiters.Add(source);
            return(source.Task);
        }
Beispiel #2
0
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            this.CheckDispose();
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("totalMilliSeconds", millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCancellation <bool>(cancellationToken));
            }
            object      lockObj = this.m_lockObj;
            Task <bool> result;

            lock (lockObj)
            {
                if (this.m_currentCount > 0)
                {
                    this.m_currentCount--;
                    if (this.m_waitHandle != null && this.m_currentCount == 0)
                    {
                        this.m_waitHandle.Reset();
                    }
                    result = SemaphoreSlim.s_trueTask;
                }
                else
                {
                    SemaphoreSlim.TaskNode taskNode = this.CreateAndAddAsyncWaiter();
                    result = ((millisecondsTimeout == -1 && !cancellationToken.CanBeCanceled) ? taskNode : this.WaitUntilCountOrTimeoutAsync(taskNode, millisecondsTimeout, cancellationToken));
                }
            }
            return(result);
        }
Beispiel #3
0
 public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
 {
     this.CheckDispose();
     if (millisecondsTimeout < -1)
     {
         throw new ArgumentOutOfRangeException("totalMilliSeconds", (object)millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
     }
     if (cancellationToken.IsCancellationRequested)
     {
         return(Task.FromCancellation <bool>(cancellationToken));
     }
     lock (this.m_lockObj)
     {
         if (this.m_currentCount > 0)
         {
             this.m_currentCount = this.m_currentCount - 1;
             if (this.m_waitHandle != null && this.m_currentCount == 0)
             {
                 this.m_waitHandle.Reset();
             }
             return(SemaphoreSlim.s_trueTask);
         }
         SemaphoreSlim.TaskNode local_3 = this.CreateAndAddAsyncWaiter();
         return(millisecondsTimeout != -1 || cancellationToken.CanBeCanceled ? this.WaitUntilCountOrTimeoutAsync(local_3, millisecondsTimeout, cancellationToken) : (Task <bool>)local_3);
     }
 }
Beispiel #4
0
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDisposed();
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            var source = new TaskCompletionSource <bool>();

            if (_canEnter.Wait(0, cancellationToken))
            {
                if (TryOffset(-1, out var dummy))
                {
                    source.SetResult(true);
                    return(source.Task);
                }
            }
            RootedTimeout.Launch
            (
                () =>
            {
                try
                {
                    source.SetResult(false);
                }
                catch (InvalidCastException exception)
                {
                    // Already cancelled
                    GC.KeepAlive(exception);
                }
            },
                millisecondsTimeout,
                cancellationToken
            );
            cancellationToken.Register
            (
                () =>
            {
                try
                {
                    source.SetCanceled();
                }
                catch (InvalidOperationException exception)
                {
                    // Already timeout
                    GC.KeepAlive(exception);
                }
            }
            );
            AddWaiter(source);
            return(source.Task);
        }
        public Task WaitAsync(CancellationToken cancellationToken)
        {
            CheckDisposed();
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCancellation(cancellationToken));
            }
            var source = new TaskCompletionSource <bool>();

            cancellationToken.Register(() => source.SetCanceled());
            _asyncWaiters.Add(source);
            return(source.Task);
        }
Beispiel #6
0
        public Task <bool> WaitAsync(TimeSpan timeout, CancellationToken cancellationToken) // TODO: Test coverage?
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            CheckDisposed();
            var source = new TaskCompletionSource <bool>();

            if (Wait(0, cancellationToken))
            {
                source.SetResult(true);
                return(source.Task);
            }
            Thread.MemoryBarrier();
            Theraot.Threading.Timeout.Launch
            (
                () =>
            {
                try
                {
                    source.SetResult(false);
                }
                catch (InvalidOperationException exception)
                {
                    // Already cancelled
                    GC.KeepAlive(exception);
                }
            },
                timeout,
                cancellationToken
            );
            cancellationToken.Register
            (
                () =>
            {
                try
                {
                    source.SetCanceled();
                }
                catch (InvalidOperationException exception)
                {
                    // Already timeout
                    GC.KeepAlive(exception);
                }
            }
            );
            _asyncWaiters.Add(source);
            return(source.Task);
        }
        public Task <bool> WaitAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            CheckDisposed();
            var source = new TaskCompletionSource <bool>();

            GC.KeepAlive
            (
                new Theraot.Threading.Timeout
                (
                    () =>
            {
                try
                {
                    source.SetResult(false);
                }
                catch (InvalidOperationException exception)
                {
                    // Already cancelled
                    GC.KeepAlive(exception);
                }
            },
                    timeout,
                    cancellationToken
                )
            {
                Rooted = true
            }
            );
            cancellationToken.Register
            (
                () =>
            {
                try
                {
                    source.SetCanceled();
                }
                catch (InvalidOperationException exception)
                {
                    // Already timeout
                    GC.KeepAlive(exception);
                }
            }
            );
            _asyncWaiters.Add(source);
            return(source.Task);
        }
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            CheckDisposed();
            var source = new TaskCompletionSource <bool>();

            Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken);
            cancellationToken.Register(() => source.SetCanceled());
            _asyncWaiters.Add(source);
            return(source.Task);
        }
Beispiel #9
0
        /// <summary>
        /// Asynchronously waits to enter the <see cref="SemaphoreSlim"/>,
        /// using a 32-bit signed integer to measure the time interval,
        /// while observing a <see cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">
        /// The number of milliseconds to wait, or <see cref="Timeout.Infinite"/>(-1) to wait indefinitely.
        /// </param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to observe.</param>
        /// <returns>
        /// A task that will complete with a result of true if the current thread successfully entered
        /// the <see cref="SemaphoreSlim"/>, otherwise with a result of false.
        /// </returns>
        /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
        /// disposed.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1,
        /// which represents an infinite time-out.
        /// </exception>
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDispose();

            // Validate input
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
            }

            // Bail early for cancellation
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCancellation <bool>(cancellationToken));
            }

            using (LockHolder.Hold(m_lock))
            {
                // If there are counts available, allow this waiter to succeed.
                if (m_currentCount > 0)
                {
                    --m_currentCount;
                    if (m_waitHandle != null && m_currentCount == 0)
                    {
                        m_waitHandle.Reset();
                    }
                    return(s_trueTask);
                }
                else if (millisecondsTimeout == 0)
                {
                    // No counts, if timeout is zero fail fast
                    return(s_falseTask);
                }
                // If there aren't, create and return a task to the caller.
                // The task will be completed either when they've successfully acquired
                // the semaphore or when the timeout expired or cancellation was requested.
                else
                {
                    Debug.Assert(m_currentCount == 0, "m_currentCount should never be negative");
                    var asyncWaiter = CreateAndAddAsyncWaiter();
                    return((millisecondsTimeout == Timeout.Infinite && !cancellationToken.CanBeCanceled) ?
                           asyncWaiter :
                           WaitUntilCountOrTimeoutAsync(asyncWaiter, millisecondsTimeout, cancellationToken));
                }
            }
        }
Beispiel #10
0
        public Task WaitAsync(CancellationToken cancellationToken) // TODO: Test coverage?
        {
            CheckDisposed();
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCancellation(cancellationToken));
            }
            var source = new TaskCompletionSource <bool>();

            if (Wait(0, cancellationToken))
            {
                source.SetResult(true);
                return(source.Task);
            }
            Thread.MemoryBarrier();
            cancellationToken.Register(() => source.SetCanceled());
            _asyncWaiters.Add(source);
            return(source.Task);
        }
Beispiel #11
0
        public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) // TODO: Test coverage?
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task <bool> .FromCancellation(cancellationToken));
            }
            CheckDisposed();
            var source = new TaskCompletionSource <bool>();

            if (TryEnter())
            {
                source.SetResult(true);
                return(source.Task);
            }
            Thread.MemoryBarrier();
            Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken); // TODO: Review
            cancellationToken.Register(() => source.SetCanceled());
            _asyncWaiters.Add(source);
            return(source.Task);
        }