File: src\VisualStudio\IntegrationTest\Harness\XUnitShared\Threading\SemaphoreExtensions.cs
Web Access
Project: src\src\VisualStudio\IntegrationTest\Harness\XUnit\Microsoft.VisualStudio.Extensibility.Testing.Xunit.csproj (Microsoft.VisualStudio.Extensibility.Testing.Xunit)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
namespace Xunit.Threading
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;
 
    internal static class SemaphoreExtensions
    {
        public static SemaphoreDisposer DisposableWait(this Semaphore semaphore, CancellationToken cancellationToken)
        {
            if (cancellationToken.CanBeCanceled)
            {
                var signalledIndex = WaitHandle.WaitAny(new[] { semaphore, cancellationToken.WaitHandle });
                if (signalledIndex != 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    throw ExceptionUtilities.Unreachable;
                }
            }
            else
            {
                semaphore.WaitOne();
            }
 
            return new SemaphoreDisposer(semaphore);
        }
 
        public static Task<SemaphoreDisposer> DisposableWaitAsync(this Semaphore semaphore, CancellationToken cancellationToken)
        {
            return Task.Factory.StartNew(
                () => DisposableWait(semaphore, cancellationToken),
                cancellationToken,
                TaskCreationOptions.LongRunning,
                TaskScheduler.Default);
        }
 
        internal struct SemaphoreDisposer : IDisposable
        {
            private readonly Semaphore _semaphore;
 
            public SemaphoreDisposer(Semaphore semaphore)
            {
                _semaphore = semaphore;
            }
 
            public void Dispose()
            {
                _semaphore.Release();
            }
        }
    }
}