Ejemplo n.º 1
3
        public static void RunSpinLockTest0_Enter(int threadsCount, bool enableThreadIDs)
        {
            // threads array
            Task[] threads = new Task[threadsCount];
            //spinlock object
            SpinLock slock = new SpinLock(enableThreadIDs);
            // succeeded threads counter
            int succeeded = 0;
            // Semaphore used to make sure that there is no other threads in the critical section
            SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);

            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = Task.Run(delegate ()
                {
                    bool lockTaken = false;
                    try
                    {
                        slock.Enter(ref lockTaken);
                        //use semaphore to make sure that no other thread inside the critical section
                        if (!semaphore.Wait(0))
                        {
                            // This mean that there is another thread in the critical section
                            return;
                        }
                        succeeded++;
                        if (slock.IsThreadOwnerTrackingEnabled && !slock.IsHeldByCurrentThread)
                        {
                            // lock is obtained successfully
                            succeeded--;
                        }
                    }
                    catch
                    {
                        // decrement the count in case of exception
                        succeeded--;
                    }
                    finally
                    {
                        semaphore.Release();
                        if (lockTaken)
                        {
                            slock.Exit();
                        }
                    }
                });
            }
            // wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Wait();
            }
            // count must be equal to the threads count
            Assert.Equal(threadsCount, succeeded);
        }
Ejemplo n.º 2
2
 /// <summary>
 /// Test SemaphoreSlim Release
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="releaseCount">The release count for the release method</param>
 /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
 /// null for valid cases</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest2_Release
    (int initial, int maximum, int releaseCount, Type exceptionType)
 {
     SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
     try
     {
         int oldCount = semaphore.Release(releaseCount);
         Assert.Equal(initial, oldCount);
         Assert.Equal(initial + releaseCount, semaphore.CurrentCount);
     }
     catch (Exception ex)
     {
         Assert.NotNull(exceptionType);
         Assert.IsType(exceptionType, ex);
     }
 }
        public static void CancelAfterWait()
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0); // semaphore that will block all waiters

            Task.Run(
                () =>
                {
                    for (int i = 0; i < 300; i++) ;
                    cancellationTokenSource.Cancel();
                });

            //Now wait.. the wait should abort and an exception should be thrown
            EnsureOperationCanceledExceptionThrown(
               () => semaphoreSlim.Wait(cancellationToken),
               cancellationToken, "CancelAfterWait:  An OCE(null) should have been thrown that references the cancellationToken.");

            // the token should not have any listeners.
            // currently we don't expose this.. but it was verified manually
        }
Ejemplo n.º 4
1
 /// <summary>
 /// Test SemaphoreSlim AvailableWaitHandle property
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="action">SemaphoreSlim action to be called before WaitHandle</param>
 /// <param name="state">The expected wait handle state</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest7_AvailableWaitHandle(int initial, int maximum, SemaphoreSlimActions? action, bool state)
 {
     SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
     try
     {
         CallSemaphoreAction(semaphore, action, null);
         if (semaphore.AvailableWaitHandle == null)
         {
             string methodFailed = "RunSemaphoreSlimTest7_AvailableWaitHandle(" + initial + "," + maximum + "," + action + "): FAILED.  ";
             Assert.True(false, string.Format(methodFailed + "AvailableWaitHandle failed, handle is null."));
         }
         if (semaphore.AvailableWaitHandle.WaitOne(0) != state)
         {
             string methodFailed = "RunSemaphoreSlimTest7_AvailableWaitHandle(" + initial + "," + maximum + "," + action + "): FAILED.  ";
             Assert.True(false, string.Format(methodFailed + "AvailableWaitHandle failed, expected " + state + " actual " + !state));
         }
     }
     catch (Exception ex)
     {
         string methodFailed = "RunSemaphoreSlimTest7_AvailableWaitHandle(" + initial + "," + maximum + "," + action + "): FAILED.  ";
         Assert.True(false, string.Format(methodFailed + "AvailableWaitHandle failed, the code threw exception " + ex));
     }
 }
        public static void CancelBeforeWait()
        {
            SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2);

            CancellationTokenSource cs = new CancellationTokenSource();
            cs.Cancel();
            CancellationToken ct = cs.Token;

            const int millisec = 100;
            TimeSpan timeSpan = new TimeSpan(100);
            EnsureOperationCanceledExceptionThrown(() => semaphoreSlim.Wait(ct), ct, "CancelBeforeWait:  An OCE should have been thrown.");
            EnsureOperationCanceledExceptionThrown(() => semaphoreSlim.Wait(millisec, ct), ct, "CancelBeforeWait:  An OCE should have been thrown.");
            EnsureOperationCanceledExceptionThrown(() => semaphoreSlim.Wait(timeSpan, ct), ct, "CancelBeforeWait:  An OCE should have been thrown.");
            semaphoreSlim.Dispose();
        }
Ejemplo n.º 6
0
 public static SemaphoreDisposer DisposableWait(this SemaphoreSlim semaphore, CancellationToken cancellationToken = default)
 {
     semaphore.Wait(cancellationToken);
     return(new SemaphoreDisposer(semaphore));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Semaphore"/> class.
 /// </summary>
 protected Semaphore(SemaphoreSlim semaphore)
 {
     this.Instance = semaphore;
 }
Ejemplo n.º 8
0
 public static Scope Lock(this SemaphoreSlim ss, TimeSpan timeout)
 {
     return(Scope.Create(
                () => ss.Wait(timeout),
                () => ss.Release()));
 }
Ejemplo n.º 9
0
 static HttpRequestor()
 {
     ServicePointManager.SecurityProtocol       = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12;
     ServicePointManager.DefaultConnectionLimit = Environment.ProcessorCount;
     availableConnections = new SemaphoreSlim(ServicePointManager.DefaultConnectionLimit);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Test SemaphoreSlim WaitAsync and Release methods concurrently
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="waitThreads">Number of the threads that call Wait method</param>
        /// <param name="releaseThreads">Number of the threads that call Release method</param>
        /// <param name="succeededWait">Number of succeeded wait threads</param>
        /// <param name="failedWait">Number of failed wait threads</param>
        /// <param name="finalCount">The final semaphore count</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest8_ConcWaitAsyncAndRelease(int initial, int maximum,
            int waitThreads, int releaseThreads, int succeededWait, int failedWait, int finalCount, int timeout)
        {
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
            Task[] tasks = new Task[waitThreads + releaseThreads];
            int succeeded = 0;
            int failed = 0;
            ManualResetEvent mre = new ManualResetEvent(false);
            // launch threads
            for (int i = 0; i < tasks.Length; i++)
            {
                if (i < waitThreads)
                {
                    tasks[i] = Task.Run(async delegate
                    {
                        mre.WaitOne();
                        if (await semaphore.WaitAsync(timeout))
                        {
                            Interlocked.Increment(ref succeeded);
                        }
                        else
                        {
                            Interlocked.Increment(ref failed);
                        }
                    });
                }
                else
                {
                    tasks[i] = Task.Run(delegate
                    {
                        mre.WaitOne();
                        semaphore.Release();
                    });
                }
            }

            mre.Set();
            //wait work to be done;
            Task.WaitAll(tasks);

            Assert.Equal(succeededWait, succeeded);
            Assert.Equal(failedWait, failed);
            Assert.Equal(finalCount, semaphore.CurrentCount);
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Test SemaphoreSlim Dispose
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="action">SemaphoreSlim action to be called after Dispose</param>
 /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
 /// null for valid cases</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest4_Dispose(int initial, int maximum, SemaphoreSlimActions? action, Type exceptionType)
 {
     SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
     try
     {
         semaphore.Dispose();
         CallSemaphoreAction(semaphore, action, null);
     }
     catch (Exception ex)
     {
         Assert.NotNull(exceptionType);
         Assert.IsType(exceptionType, ex);
     }
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Test SemaphoreSlim WaitAsync
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="timeout">The timeout parameter for the wait method, it must be either int or TimeSpan</param>
 /// <param name="returnValue">The expected wait return value</param>
 /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
 /// null for valid cases</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest1_WaitAsync
     (int initial, int maximum, object timeout, bool returnValue, Type exceptionType)
 {
     SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
     try
     {
         bool result = false;
         if (timeout is TimeSpan)
         {
             result = semaphore.WaitAsync((TimeSpan)timeout).Result;
         }
         else
         {
             result = semaphore.WaitAsync((int)timeout).Result;
         }
         Assert.Equal(returnValue, result);
         if (result)
         {
             Assert.Equal(initial - 1, semaphore.CurrentCount);
         }
     }
     catch (Exception ex)
     {
         Assert.NotNull(exceptionType);
         Assert.IsType(exceptionType, ex);
     }
 }
Ejemplo n.º 13
0
 public AccessTokenProvider(IDialogService dialogService, Func <LoginViewModel> loginViewModelFactory)
 {
     this.semaphoreSlim         = new SemaphoreSlim(1);
     this.dialogService         = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
     this.loginViewModelFactory = loginViewModelFactory ?? throw new ArgumentNullException(nameof(loginViewModelFactory));
 }
Ejemplo n.º 14
0
 public SafeSemaphoreRelease(SemaphoreSlim currentSemaphore, SemaphoreSlim nextSemaphore, AsyncLock asyncLock)
 {
     _currentSemaphore = currentSemaphore;
     _nextSemaphore    = nextSemaphore;
     _asyncLock        = asyncLock;
 }
Ejemplo n.º 15
0
        private async Task <IAsyncDisposable> TakeLockCoreAsync(SemaphoreSlim currentSemaphore, SafeSemaphoreRelease safeSemaphoreRelease)
        {
            await currentSemaphore.WaitAsync();

            return(safeSemaphoreRelease);
        }
Ejemplo n.º 16
0
 public AsyncLock()
 {
     _topLevelSemaphore = s_semaphorePool.Get();
     _currentSemaphore  = new AsyncLocal <SemaphoreSlim>();
 }
Ejemplo n.º 17
0
    private static async Task <Task> RunSlowAsync <TState>(this SemaphoreSlim semaphoreSlim, Func <TState, Task> callback, TState state)
    {
        await semaphoreSlim.WaitAsync();

        return(RunTask(callback, semaphoreSlim, state));
    }
Ejemplo n.º 18
0
 public SemaphoreDisposer(SemaphoreSlim semaphore)
 {
     _semaphore = semaphore;
 }
Ejemplo n.º 19
0
        public async static Task <SemaphoreDisposer> DisposableWaitAsync(this SemaphoreSlim semaphore, CancellationToken cancellationToken = default)
        {
            await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

            return(new SemaphoreDisposer(semaphore));
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Test SemaphoreSlim Wait and Release methods concurrently
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="waitThreads">Number of the threads that call Wait method</param>
        /// <param name="releaseThreads">Number of the threads that call Release method</param>
        /// <param name="succeededWait">Number of succeeded wait threads</param>
        /// <param name="failedWait">Number of failed wait threads</param>
        /// <param name="finalCount">The final semaphore count</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest8_ConcWaitAndRelease(int initial, int maximum,
            int waitThreads, int releaseThreads, int succeededWait, int failedWait, int finalCount, int timeout)
        {
            string methodFailed =
                "RunSemaphoreSlimTest8_ConcWaitAndRelease("
                + initial + "," + maximum + "," + waitThreads + ", " + releaseThreads + ", "
                + succeededWait + ", " + failedWait + ", " + finalCount + ", " + timeout + "): FAILED.  ";
            try
            {
                SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
                Task[] threads = new Task[waitThreads + releaseThreads];
                int succeeded = 0;
                int failed = 0;
                ManualResetEvent mre = new ManualResetEvent(false);
                // launch threads
                for (int i = 0; i < threads.Length; i++)
                {
                    if (i < waitThreads)
                    {
                        // We are creating the Task using TaskCreationOptions.LongRunning to
                        // force usage of another thread (which will be the case on the default scheduler
                        // with its current implementation).  Without this, the release tasks will likely get
                        // queued behind the wait tasks in the pool, making it very likely that the wait tasks
                        // will starve the very tasks that when run would unblock them.
                        threads[i] = new Task(delegate ()
                           {
                               mre.WaitOne();
                               if (semaphore.Wait(timeout))
                               {
                                   Interlocked.Increment(ref succeeded);
                               }
                               else
                               {
                                   Interlocked.Increment(ref failed);
                               }
                           }, TaskCreationOptions.LongRunning);
                    }
                    else
                    {
                        threads[i] = new Task(delegate ()
                           {
                               mre.WaitOne();
                               semaphore.Release();
                           });
                    }
                    threads[i].Start(TaskScheduler.Default);
                }

                mre.Set();
                //wait work to be done;
                Task.WaitAll(threads);
                //check the number of succeeded and failed wait
                if (succeeded != succeededWait || failed != failedWait || semaphore.CurrentCount != finalCount)
                {
                    Debug.WriteLine(methodFailed + "ConcurrentWaitRelease failed. This might not be a bug, if the system was unstable during the test.");
                    Assert.True(false, string.Format(methodFailed + "Expected succeeded={0}, failed={1}, count={2}, but got {3}, {4}, {5}",
                        succeededWait, failedWait, finalCount, succeeded, failed, semaphore.CurrentCount));
                }
            }
            catch (Exception ex)
            {
                Assert.True(false, string.Format(methodFailed + "ConcurrentWaitRelease failed, the code threw exception " + ex));
            }
        }
Ejemplo n.º 21
0
        private static void TestConcurrentWaitAndWaitAsync(int syncWaiters, int asyncWaiters)
        {
            string methodFailed = "ConcurrentWaitAndWaitAsync(" + syncWaiters + "," + asyncWaiters + "): FAILED.";

            int totalWaiters = syncWaiters + asyncWaiters;
            if (totalWaiters < 2)
            {
                Assert.True(false, string.Format(methodFailed + " invalid waiter arguments... need at least 2 waiters"));
            }

            var semaphore = new SemaphoreSlim(0);
            Task[] tasks = new Task[totalWaiters];

            const int ITERS = 10;
            int randSeed = (int)DateTime.Now.Ticks;
            for (int i = 0; i < syncWaiters; i++)
            {
                tasks[i] = Task.Run(delegate
                {
                    //Random rand = new Random(Interlocked.Increment(ref randSeed));
                    for (int iter = 0; iter < ITERS; iter++)
                    {
                        semaphore.Wait();
                        semaphore.Release();
                    }
                });
            }
            for (int i = syncWaiters; i < totalWaiters; i++)
            {
                tasks[i] = Task.Run(async delegate
                {
                    //Random rand = new Random(Interlocked.Increment(ref randSeed));
                    for (int iter = 0; iter < ITERS; iter++)
                    {
                        await semaphore.WaitAsync();
                        semaphore.Release();
                    }
                });
            }

            semaphore.Release(totalWaiters / 2);
            Task.WaitAll(tasks);
        }
Ejemplo n.º 22
0
 public CreatePerformance(IInstrumentation instrumentation, int maxConcurrentRequests, CancellationToken cancellationToken)
 {
     this.cancellationToken = cancellationToken;
     this.instrumentation   = instrumentation;
     this.semaphore         = new SemaphoreSlim(maxConcurrentRequests, maxConcurrentRequests);
 }
Ejemplo n.º 23
0
 public SocketGroup(Dictionary <UdpClient, List <IPAddress> > sockets, int defaultPort)
 {
     Sockets          = sockets;
     DefaultPort      = defaultPort;
     SocketSendLocker = new SemaphoreSlim(1, 1);
 }
 public WaitQueue(int count)
 {
     _semaphore = new SemaphoreSlim(count);
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Test SemaphoreSlim AvailableWaitHandle property
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="action">SemaphoreSlim action to be called before WaitHandle</param>
        /// <param name="state">The expected wait handle state</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest7_AvailableWaitHandle(int initial, int maximum, SemaphoreSlimActions? action, bool state)
        {
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);

            CallSemaphoreAction(semaphore, action, null);
            Assert.NotNull(semaphore.AvailableWaitHandle);
            Assert.Equal(state, semaphore.AvailableWaitHandle.WaitOne(0));
        }
 public SemaphoreLockStruct(SemaphoreSlim sem)
 {
     this.sem = sem;
 }
 public static SemaphoreLockStruct Lock(this SemaphoreSlim sem)
 {
     sem.Wait();
     return(new SemaphoreLockStruct(sem));
 }
Ejemplo n.º 28
0
        /// <summary>
        /// Test SemaphoreSlim constructor
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
        /// null for valid cases</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest0_Ctor(int initial, int maximum, Type exceptionType)
        {
            string methodFailed = "RunSemaphoreSlimTest0_Ctor(" + initial + "," + maximum + "):  FAILED.  ";
            Exception exception = null;
            try
            {
                SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
                if (semaphore.CurrentCount != initial)
                {
                    Assert.True(false, string.Format(methodFailed + "Constructor test failed, expected " + initial + " actual " + semaphore.CurrentCount));
                }
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            // The code threw excption and it is not expected because the excyptionType param is null
            if (exceptionType == null && exception != null)
            {
                Assert.True(false, string.Format(methodFailed + "Constructor failed, the code threw an exception, and it is not supposed to."));
            }

            // Compare both exception types in case of the code threw exception
            if (exception != null && !Type.Equals(exception.GetType(), exceptionType))
            {
                Assert.True(false, string.Format(methodFailed + "Constructor failed, Excption types do not match"));
            }
        }
Ejemplo n.º 29
0
 public static Scope Lock(this SemaphoreSlim ss, int timeout_ms)
 {
     return(Scope.Create(
                () => ss.Wait(timeout_ms),
                () => ss.Release()));
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Test SemaphoreSlim Release
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="releaseCount">The release count for the release method</param>
        /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
        /// null for valid cases</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest2_Release
           (int initial, int maximum, int releaseCount, Type exceptionType)
        {
            string methodFailed = "RunSemaphoreSlimTest2_Release(" + initial + "," + maximum + "," + releaseCount + "):  FAILED.  ";
            Exception exception = null;
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
            try
            {
                int oldCount = semaphore.Release(releaseCount);
                if (semaphore.CurrentCount != initial + releaseCount || oldCount != initial)
                {
                    Assert.True(false, string.Format(methodFailed + "Release failed, the method returned " + oldCount + " and expected " + initial));
                }
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            // The code threw excption and it is not expected because the excyptionType param is null
            if (exceptionType == null && exception != null)
            {
                Assert.True(false, string.Format(methodFailed + "Release failed, the code threw an exception, and it is not supposed to."));
            }

            // Compare both exception types in case of the code threw exception
            if (exception != null && !Type.Equals(exception.GetType(), exceptionType))
            {
                Assert.True(false, string.Format(methodFailed + "Release failed, Excption types do not match"));
            }
        }
Ejemplo n.º 31
0
 public static Scope Lock(this SemaphoreSlim ss, TimeSpan timeout, CancellationToken cancel)
 {
     return(Scope.Create(
                () => ss.Wait(timeout, cancel),
                () => ss.Release()));
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Test SemaphoreSlim CurrentCount property
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="action">SemaphoreSlim action to be called before CurentCount</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest5_CurrentCount(int initial, int maximum, SemaphoreSlimActions? action)
 {
     SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
     try
     {
         CallSemaphoreAction(semaphore, action, null);
         if ((action == SemaphoreSlimActions.Wait && semaphore.CurrentCount != initial - 1)
         || (action == SemaphoreSlimActions.WaitAsync && semaphore.CurrentCount != initial - 1)
         || (action == SemaphoreSlimActions.Release && semaphore.CurrentCount != initial + 1))
         {
             string methodFailed = "RunSemaphoreSlimTest5_CurrentCount(" + initial + "," + maximum + "," + action + "): FAILED.  ";
             Assert.True(false, string.Format(methodFailed + "CurrentCount failed"));
         }
     }
     catch (Exception ex)
     {
         string methodFailed = "RunSemaphoreSlimTest5_CurrentCount(" + initial + "," + maximum + "," + action + "): FAILED.  ";
         Assert.True(false, string.Format(methodFailed + "CurrentCount failed, the code threw exception " + ex));
     }
 }
        public async static Task <SemaphoreLockStruct> LockAsync(this SemaphoreSlim sem)
        {
            await sem.WaitAsync();

            return(new SemaphoreLockStruct(sem));
        }
Ejemplo n.º 34
0
        private async Task UploadAsync(CancellationToken ct, string item, string uploadPath, SemaphoreSlim clientThrottle, bool allowOverwrite)
        {
            if (!File.Exists(item))
            {
                throw new Exception(string.Format("The file '{0}' does not exist.", item));
            }

            await clientThrottle.WaitAsync();

            string         leaseId   = string.Empty;
            AzureBlobLease blobLease = new AzureBlobLease(feed.AccountName, feed.AccountKey, string.Empty, feed.ContainerName, uploadPath, Log, "60", "10");

            bool isLeaseRequired = allowOverwrite && await feed.CheckIfBlobExists(uploadPath);

            if (isLeaseRequired)
            {
                try
                {
                    leaseId = blobLease.Acquire();
                }
                catch (Exception)
                {
                    Log.LogError($"Unable to obtain lease on {uploadPath}");
                }
            }
            try
            {
                bool isExists = await feed.CheckIfBlobExists(uploadPath);

                if (!isExists || allowOverwrite)
                {
                    Log.LogMessage($"Uploading {item} to {uploadPath}.");
                    UploadClient uploadClient = new UploadClient(Log);
                    await
                    uploadClient.UploadBlockBlobAsync(
                        ct,
                        feed.AccountName,
                        feed.AccountKey,
                        feed.ContainerName,
                        item,
                        uploadPath,
                        leaseId);
                }
                else
                {
                    Log.LogMessage($"Skipping uploading of {item} to {uploadPath}. Already exists.");
                }
            }
            catch (Exception)
            {
                Log.LogError($"Unable to upload to {uploadPath}");
            }
            finally
            {
                if (isLeaseRequired)
                {
                    blobLease.Release();
                }
                clientThrottle.Release();
            }
        }
Ejemplo n.º 35
0
        /// <summary>
        /// Test SemaphoreSlim WaitAsync
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="timeout">The timeout parameter for the wait method, it must be either int or TimeSpan</param>
        /// <param name="returnValue">The expected wait return value</param>
        /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
        /// null for valid cases</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest1_WaitAsync
            (int initial, int maximum, object timeout, bool returnValue, Type exceptionType)
        {
            string methodFailed = "RunSemaphoreSlimTest1_WaitAsync(" + initial + "," + maximum + "," + timeout + "):  FAILED.  ";
            Exception exception = null;
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
            try
            {
                bool result = false;
                if (timeout is TimeSpan)
                {
                    result = semaphore.WaitAsync((TimeSpan)timeout).Result;
                }
                else
                {
                    result = semaphore.WaitAsync((int)timeout).Result;
                }

                if (result != returnValue ||
                (result && semaphore.CurrentCount != initial - 1))
                {
                    Assert.True(false, string.Format(methodFailed + "WaitAsync failed, the method returned " + result + " and expected " + returnValue));
                }
            }
            catch (AggregateException ex)
            {
                exception = ex.InnerException;
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            // The code threw excption and it is not expected because the excyptionType param is null
            if (exceptionType == null && exception != null)
            {
                Assert.True(false, string.Format(methodFailed + "WaitAsync failed, the code threw an exception, and it is not supposed to."));
            }

            // Compare both exception types in case of the code threw exception
            if (exception != null && !Type.Equals(exception.GetType(), exceptionType))
            {
                Assert.True(false, string.Format(methodFailed + "WaitAsync failed, Excption types do not match"));
            }
        }
Ejemplo n.º 36
0
 internal TreeWriter(StorageEnvironment env)
 {
     _env           = env;
     _pendingWrites = new ConcurrentQueue <OutstandingWrite>();
     _semaphore     = new SemaphoreSlim(1, 1);
 }
Ejemplo n.º 37
0
        /// <summary>
        /// Test SemaphoreSlim Dispose
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="action">SemaphoreSlim action to be called after Dispose</param>
        /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
        /// null for valid cases</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest4_Dispose(int initial, int maximum, SemaphoreSlimActions? action, Type exceptionType)
        {
            Exception exception = null;
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
            try
            {
                semaphore.Dispose();
                CallSemaphoreAction(semaphore, action, null);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            // The code threw excption and it is not expected because the excyptionType param is null
            if (exceptionType == null && exception != null)
            {
                string methodFailed = "RunSemaphoreSlimTest4_Dispose(" + initial + "," + maximum + "," + action + "): FAILED.  ";
                Assert.True(false, string.Format(methodFailed + "Dispose failed, the code threw an exception, and it is not supposed to."));
            }

            // Compare both exception types in case of the code threw exception
            if (exception != null && !Type.Equals(exception.GetType(), exceptionType))
            {
                string methodFailed = "RunSemaphoreSlimTest4_Dispose(" + initial + "," + maximum + "," + action + "): FAILED.  ";
                Assert.True(false, string.Format(methodFailed + "Dispose failed, Excption types do not match"));
            }
        }
Ejemplo n.º 38
0
 public ProcessLock(string name)
 {
     Name      = name;
     Semaphore = new SemaphoreSlim(1);
 }
Ejemplo n.º 39
0
        public void SendToOneChannel(object stateInfo)
        {
            var descriptor = (ChannelDescriptor)stateInfo;

            _identityProvider.Identity = new Identity(descriptor.CustomerCode);

            var channelService = ObjectFactoryBase.Resolve <INotificationChannelService>();
            var config         = ConfigDictionary[descriptor.CustomerCode];

            try
            {
                var key   = GetKey(descriptor.ChannelName, descriptor.CustomerCode);
                var state = _lockers[key];

                if (Monitor.TryEnter(state))
                {
                    try
                    {
                        if (!state.BlockState.HasValue ||
                            state.BlockState.Value.AddSeconds(config.WaitIntervalAfterErrors) <= DateTime.Now)
                        {
                            if (state.BlockState.HasValue)
                            {
                                _logger.Info(
                                    "Temporary channel lock has been released for channel {channel}, customer code {customerCode}",
                                    descriptor.ChannelName, descriptor.CustomerCode
                                    );
                                state.BlockState =
                                    null; //снимаем блокировку, если прошел указанные интервал и пробуем отправить снова
                            }

                            var service = ObjectFactoryBase.Resolve <IMessageService>();
                            var res     = service.GetMessagesToSend(descriptor.ChannelName, config.PackageSize);

                            if (res.IsSucceeded)
                            {
                                var channel    = GetChannel(config, descriptor.ChannelName);
                                var semaphore  = new SemaphoreSlim(Math.Max(channel.DegreeOfParallelism, 1));
                                var localState = new ChannelState()
                                {
                                    ErrorsCount = 0
                                };
                                var factoryMap = res.Result.Select(m => m.Key).Distinct()
                                                 .ToDictionary(k => k, k => new TaskFactory(new OrderedTaskScheduler()));
                                var tasks = res.Result
                                            .Select(m => SendOneMessage(descriptor.CustomerCode, descriptor.InstanceId, config,
                                                                        channel, service, m, semaphore, factoryMap[m.Key], localState, channelService))
                                            .ToArray();

                                Task.WaitAll(tasks);

                                if (localState.ErrorsCount >= config.ErrorCountBeforeWait)
                                {
                                    state.BlockState = DateTime.Now;
                                    _logger.Info(
                                        "Temporary channel lock has been acquired for channel {channel}, customer code {customerCode}",
                                        channel.Name, descriptor.CustomerCode
                                        );
                                }
                            }
                            else
                            {
                                state.BlockState = DateTime.Now;
                                _logger.Info(
                                    "Queue for channel {channel}, customer code {customerCode} is unavailable, temporary lock will be acquired",
                                    descriptor.ChannelName, descriptor.CustomerCode
                                    );
                            }
                        }
                    }
                    finally
                    {
                        Monitor.Exit(state);
                    }
                }
                else
                {
                    _logger.Info(
                        "Queue for channel {channel}, {customerCode} is busy",
                        descriptor.ChannelName, descriptor.CustomerCode
                        );
                }
            }
            catch (Exception ex)
            {
                _logger.Error().Exception(ex)
                .Message(
                    "An error occured while processing messages from the queue for channel {channel}, customer code {customerCode}",
                    descriptor.ChannelName, descriptor.CustomerCode
                    )
                .Write();
            }
        }
Ejemplo n.º 40
0
        private async Task SendOneMessage(
            string customerCode,
            string instanceId,
            NotificationSenderConfig config,
            NotificationChannel channel,
            IMessageService service,
            Message message,
            SemaphoreSlim semaphore,
            TaskFactory factory,
            ChannelState state,
            INotificationChannelService channelService)
        {
            await factory.StartNew(() =>
            {
                lock (state)
                {
                    if (state.ErrorsCount >= config.ErrorCountBeforeWait)
                    {
                        return;
                    }
                }

                var timer = new Stopwatch();
                timer.Start();
                string url = GetUrl(customerCode, instanceId, channel, message);

                try
                {
                    semaphore.Wait();
                    _logger.Debug("Start processing message {messageId} ", message.Id);


                    var request           = (HttpWebRequest)WebRequest.Create(url);
                    request.Method        = message.Method.ToUpper();
                    request.Timeout       = 1000 * config.TimeOut;
                    var mediaType         = !string.IsNullOrEmpty(channel.MediaType) ? channel.MediaType : "text/xml";
                    request.ContentType   = $"{mediaType}; charset=utf-8";
                    byte[] data           = Encoding.UTF8.GetBytes(message.Xml);
                    request.ContentLength = data.Length;

                    using (var streamWriter = request.GetRequestStream())
                    {
                        streamWriter.Write(data, 0, data.Length);
                        streamWriter.Flush();
                    }

                    using (var httpResponse = (HttpWebResponse)request.GetResponse())
                    {
                        timer.Stop();
                        _logger.Info()
                        .Message(
                            "Message {message} for channel {channel} has been sent on url {url}",
                            message.Method, channel.Name, Uri.UnescapeDataString(url)
                            )
                        .Property("productId", message.Key)
                        .Property("statusCode", httpResponse.StatusCode)
                        .Property("timeTaken", timer.ElapsedMilliseconds)
                        .Property("messageId", message.Id)
                        .Property("customerCode", customerCode)
                        .Write();

                        channelService.UpdateNotificationChannel(customerCode, channel.Name, message.Key,
                                                                 message.Created, httpResponse.StatusCode.ToString());
                    }

                    ;

                    service.RemoveMessage(message.Id);
                }
                catch (WebException ex)
                {
                    timer.Stop();

                    lock (state)
                    {
                        state.ErrorsCount++;
                    }

                    var httpResponse = ex.Response as HttpWebResponse;

                    if (httpResponse != null)
                    {
                        _logger.Info()
                        .Message(
                            "Message {message} for channel {channel} has been sent on url {url}",
                            message.Method, channel.Name, Uri.UnescapeDataString(url)
                            )
                        .Property("productId", message.Key)
                        .Property("statusCode", httpResponse.StatusCode)
                        .Property("timeTaken", timer.ElapsedMilliseconds)
                        .Property("messageId", message.Id)
                        .Property("customerCode", customerCode)
                        .Write();

                        channelService.UpdateNotificationChannel(customerCode, channel.Name, message.Key,
                                                                 message.Created, httpResponse.StatusCode.ToString());
                    }
                    else
                    {
                        _logger.Info()
                        .Message(
                            "Message {message} for channel {channel} has not been sent on url {url}",
                            message.Method, channel.Name, Uri.UnescapeDataString(url)
                            )
                        .Property("productId", message.Key)
                        .Property("statusCode", ex.Status)
                        .Property("timeTaken", timer.ElapsedMilliseconds)
                        .Property("messageId", message.Id)
                        .Property("customerCode", customerCode)
                        .Write();

                        channelService.UpdateNotificationChannel(customerCode, channel.Name, message.Key,
                                                                 message.Created, ex.Status.ToString());
                    }

                    _logger.Error().Exception(ex)
                    .Message(
                        "Message {message} for channel {channel} has not been sent on url {url}",
                        message.Method, channel.Name, Uri.UnescapeDataString(url)
                        )
                    .Property("productId", message.Key)
                    .Property("timeTaken", timer.ElapsedMilliseconds)
                    .Property("messageId", message.Id)
                    .Property("customerCode", customerCode)
                    .Write();
                }
                finally
                {
                    semaphore.Release();
                }
            });
        }
Ejemplo n.º 41
0
        /// <summary>
        /// Test SemaphoreSlim WaitAsync and Release methods concurrently
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="waitThreads">Number of the threads that call Wait method</param>
        /// <param name="releaseThreads">Number of the threads that call Release method</param>
        /// <param name="succeededWait">Number of succeeded wait threads</param>
        /// <param name="failedWait">Number of failed wait threads</param>
        /// <param name="finalCount">The final semaphore count</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest8_ConcWaitAsyncAndRelease(int initial, int maximum,
            int waitThreads, int releaseThreads, int succeededWait, int failedWait, int finalCount, int timeout)
        {
            string methodFailed =
                "RunSemaphoreSlimTest8_ConcWaitAsyncAndRelease(" + initial + "," + maximum + "," + waitThreads + ", " + releaseThreads + "):  FAILED. ";
            try
            {
                SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
                Task[] tasks = new Task[waitThreads + releaseThreads];
                int succeeded = 0;
                int failed = 0;
                ManualResetEvent mre = new ManualResetEvent(false);
                // launch threads
                for (int i = 0; i < tasks.Length; i++)
                {
                    if (i < waitThreads)
                    {
                        tasks[i] = Task.Run(async delegate
                        {
                            mre.WaitOne();
                            if (await semaphore.WaitAsync(timeout))
                            {
                                Interlocked.Increment(ref succeeded);
                            }
                            else
                            {
                                Interlocked.Increment(ref failed);
                            }
                        });
                    }
                    else
                    {
                        tasks[i] = Task.Run(delegate
                        {
                            mre.WaitOne();
                            semaphore.Release();
                        });
                    }
                }

                mre.Set();
                //wait work to be done;
                Task.WaitAll(tasks);

                //check the number of succeeded and failed wait
                if (succeeded != succeededWait || failed != failedWait || semaphore.CurrentCount != finalCount)
                {
                    Assert.True(false, string.Format(methodFailed + "ConcurrentWaitAsyncAndRelease failed. This might not be a bug, if the system was unstable during the test."));
                }
            }
            catch (Exception ex)
            {
                Assert.True(false, string.Format(methodFailed + "ConcurrentWaitAsyncAndRelease failed, the code threw exception " + ex));
            }
        }
Ejemplo n.º 42
0
 public SingleThreadedFIFOSemaphoreSlim()
 {
     _inner = new SemaphoreSlim(1, 1);
     _queue = new ConcurrentQueue <TaskCompletionSource <bool> >();
 }
Ejemplo n.º 43
0
 /// <summary>
 /// Test SemaphoreSlim constructor
 /// </summary>
 /// <param name="initial">The initial semaphore count</param>
 /// <param name="maximum">The maximum semaphore count</param>
 /// <param name="exceptionType">The type of the thrown exception in case of invalid cases,
 /// null for valid cases</param>
 /// <returns>True if the test succeeded, false otherwise</returns>
 private static void RunSemaphoreSlimTest0_Ctor(int initial, int maximum, Type exceptionType)
 {
     string methodFailed = "RunSemaphoreSlimTest0_Ctor(" + initial + "," + maximum + "):  FAILED.  ";
     Exception exception = null;
     try
     {
         SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
         Assert.Equal(initial, semaphore.CurrentCount);
     }
     catch (Exception ex)
     {
         Assert.NotNull(exceptionType);
         Assert.IsType(exceptionType, ex);
         exception = ex;
     }
 }
Ejemplo n.º 44
0
        public async Task ThrottleLoadedItemsAsync <T>(ConcurrentQueue <T> queue, CancellationToken token,
                                                       Func <T, Task <bool> > taskToRun,
                                                       Func <T, bool, Task> taskToContinueWith, int maxConcurrentTasks = 10, int maxDegreeOfParallelism = 2)
        {
            var blockingQueue = new BlockingCollection <T>(new ConcurrentBag <T>());
            var semaphore     = new SemaphoreSlim(maxConcurrentTasks);

            var t = Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }
                        semaphore.Wait(token);
                        if (queue.TryDequeue(out var item))
                        {
                            blockingQueue.Add(item, token);
                        }
                    }
                }
                catch (Exception e)
                {
                    ErrorHandler.HandleException(e);
                }

                blockingQueue.CompleteAdding();
            }, token);

            var runningTasks = new List <Task>();

            Parallel.ForEach(IterateUntilTrue(() => blockingQueue.IsCompleted),
                             new ParallelOptions {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            },
                             async _ =>
            {
                if (blockingQueue.TryTake(out var item, 100))
                {
                    runningTasks.Add(
                        await taskToRun(item)
                        .ContinueWith(tsk =>
                    {
                        semaphore.Release();
                        return(taskToContinueWith(item, tsk.Result));
                    }, token)
                        );
                }
            });

            while (!token.IsCancellationRequested)
            {
                while (runningTasks.Any(task => !task.IsCompleted))
                {
                    await Task.WhenAny(runningTasks);

                    runningTasks.RemoveAll(task => task.IsCompleted);
                }
            }
        }
Ejemplo n.º 45
0
        /// <summary>
        /// Test SemaphoreSlim WaitAsync
        /// The test verifies that SemaphoreSlim.Release() does not execute any user code synchronously.
        /// </summary>
        private static void RunSemaphoreSlimTest1_WaitAsync2()
        {
            SemaphoreSlim semaphore = new SemaphoreSlim(1);
            ThreadLocal<int> counter = new ThreadLocal<int>(() => 0);
            bool nonZeroObserved = false;

            const int asyncActions = 20;
            int remAsyncActions = asyncActions;
            ManualResetEvent mre = new ManualResetEvent(false);

            Action<int> doWorkAsync = async delegate (int i)
            {
                await semaphore.WaitAsync();
                if (counter.Value > 0)
                {
                    nonZeroObserved = true;
                }

                counter.Value = counter.Value + 1;
                semaphore.Release();
                counter.Value = counter.Value - 1;

                if (Interlocked.Decrement(ref remAsyncActions) == 0) mre.Set();
            };

            semaphore.Wait();
            for (int i = 0; i < asyncActions; i++) doWorkAsync(i);
            semaphore.Release();

            mre.WaitOne();

            Assert.False(nonZeroObserved, "RunSemaphoreSlimTest1_WaitAsync2:  FAILED.  SemaphoreSlim.Release() seems to have synchronously invoked a continuation.");
        }
Ejemplo n.º 46
0
        async Task ProcessMessagesSwallowExceptionsAndReleaseConcurrencyLimiter(CancellationTokenSource stopBatchCancellationTokenSource, SemaphoreSlim localConcurrencyLimiter, CancellationToken messageProcessingCancellationToken)
        {
            try
            {
                try
                {
                    // We need to force the method to continue asynchronously because SqlConnection
                    // in combination with TransactionScope will apply connection pooling and enlistment synchronous in ctor.
                    await Task.Yield();

                    await processStrategy.ProcessMessage(stopBatchCancellationTokenSource, messageProcessingCancellationToken)
                    .ConfigureAwait(false);

                    messageProcessingCircuitBreaker.Success();
                }
                catch (SqlException ex) when(ex.Number == 1205)
                {
                    // getting the message was the victim of a lock resolution
                    Logger.Warn("Message processing failed", ex);
                }
                catch (Exception ex) when(!ex.IsCausedBy(messageProcessingCancellationToken))
                {
                    Logger.Warn("Message processing failed", ex);

                    await messageProcessingCircuitBreaker.Failure(ex, messageProcessingCancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception ex) when(ex.IsCausedBy(messageProcessingCancellationToken))
            {
                Logger.Debug("Message processing canceled.", ex);
            }
            finally
            {
                localConcurrencyLimiter.Release();
            }
        }
Ejemplo n.º 47
0
        /// <summary>
        /// Call specific SemaphoreSlim method or property
        /// </summary>
        /// <param name="semaphore">The SemaphoreSlim instance</param>
        /// <param name="action">The action name</param>
        /// <param name="param">The action parameter, null if it takes no parameters</param>
        /// <returns>The action return value, null if the action returns void</returns>
        private static object CallSemaphoreAction
            (SemaphoreSlim semaphore, SemaphoreSlimActions? action, object param)
        {
            if (action == SemaphoreSlimActions.Wait)
            {
                if (param is TimeSpan)
                {
                    return semaphore.Wait((TimeSpan)param);
                }
                else if (param is int)
                {
                    return semaphore.Wait((int)param);
                }
                semaphore.Wait();
                return null;
            }
            else if (action == SemaphoreSlimActions.WaitAsync)
            {
                if (param is TimeSpan)
                {
                    return semaphore.WaitAsync((TimeSpan)param).Result;
                }
                else if (param is int)
                {
                    return semaphore.WaitAsync((int)param).Result;
                }
                semaphore.WaitAsync().Wait();
                return null;
            }
            else if (action == SemaphoreSlimActions.Release)
            {
                if (param != null)
                {
                    return semaphore.Release((int)param);
                }
                return semaphore.Release();
            }
            else if (action == SemaphoreSlimActions.Dispose)
            {
                semaphore.Dispose();
                return null;
            }
            else if (action == SemaphoreSlimActions.CurrentCount)
            {
                return semaphore.CurrentCount;
            }
            else if (action == SemaphoreSlimActions.AvailableWaitHandle)
            {
                return semaphore.AvailableWaitHandle;
            }

            return null;
        }
        public static async Task <TResult> GetOrAddAsync <TKey, TResult>(this ConcurrentDictionary <TKey, TResult> dictionary, SemaphoreSlim lockObject, TKey key, Func <TKey, Task <TResult> > asyncValueFactory)
        {
            if (dictionary.TryGetValue(key, out var result))
            {
                return(result);
            }

            await lockObject.WaitAsync();

            try
            {
                if (dictionary.TryGetValue(key, out result))
                {
                    return(result);
                }

                return(dictionary[key] = await asyncValueFactory(key));
            }
            finally
            {
                lockObject.Release();
            }
        }
Ejemplo n.º 49
0
        /// <summary>
        /// Test SemaphoreSlim CurrentCount property
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="action">SemaphoreSlim action to be called before CurentCount</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest5_CurrentCount(int initial, int maximum, SemaphoreSlimActions? action)
        {
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);

            CallSemaphoreAction(semaphore, action, null);
            if (action == null)
            {
                Assert.Equal(initial, semaphore.CurrentCount);
            }
            else
            {
                Assert.Equal(initial + (action == SemaphoreSlimActions.Release ? 1 : -1), semaphore.CurrentCount);
            }
        }
Ejemplo n.º 50
0
        public async Task TheRemoteHeaderTableSizeShouldOnlyBeUsedUpToConfiguredLimit()
        {
            var inPipe      = new BufferedPipe(1024);
            var outPipe     = new BufferedPipe(1024);
            var handlerDone = new SemaphoreSlim(0);

            Func <IStream, bool> listener = (s) =>
            {
                Task.Run(() =>
                {
                    var res = new HeaderField[]
                    {
                        new HeaderField {
                            Name = ":status", Value = "200"
                        },
                    };
                    s.WriteHeadersAsync(res, false);
                });
                handlerDone.Release();
                return(true);
            };

            // Lower the initial window size so that stream window updates are
            // sent earlier than connection window updates
            var localSettings = Settings.Default;

            localSettings.HeaderTableSize = 20000;
            var http2Con = await ConnectionUtils.BuildEstablishedConnection(
                true, inPipe, outPipe, loggerProvider, listener,
                localSettings : localSettings);

            // Change remote settings, which grants us a giant header table
            var settings = Settings.Default;

            settings.HeaderTableSize = 50 * 1024 * 1024;
            await inPipe.WriteSettings(settings);

            await outPipe.AssertSettingsAck();

            // Establish a stream
            // When we send a response through it we should observe the size udpate
            var hEncoder = new Encoder();
            await inPipe.WriteHeaders(hEncoder, 1, false, DefaultGetHeaders);

            var ok = await handlerDone.WaitAsync(
                ReadableStreamTestExtensions.ReadTimeout);

            if (!ok)
            {
                throw new Exception("Stream was not created");
            }

            // Wait for the incoming status headers with header update
            var fh = await outPipe.ReadFrameHeaderWithTimeout();

            Assert.Equal(FrameType.Headers, fh.Type);
            Assert.Equal((byte)(HeadersFrameFlags.EndOfHeaders), fh.Flags);
            Assert.Equal(1u, fh.StreamId);

            // Observe headers with status update
            // We should update the header table to 20000
            Assert.Equal(5, fh.Length);
            var data = new byte[fh.Length];
            await outPipe.ReadAllWithTimeout(new ArraySegment <byte>(data));

            Assert.Equal(0x3f, data[0]); // Size Update to 20000 => 20000 - 31 = 19969
            Assert.Equal(0x81, data[1]); // 19969 % 128 + 128 = 0x81, 19969 / 128 = 156
            Assert.Equal(0x9c, data[2]); // 156 % 128 + 128 = 0x9c, 156 / 128 = 1
            Assert.Equal(0x01, data[3]); // 1
            Assert.Equal(0x88, data[4]); // :status 200
        }
Ejemplo n.º 51
0
        /// <summary>
        /// Test SemaphoreSlim Wait and Release methods concurrently
        /// </summary>
        /// <param name="initial">The initial semaphore count</param>
        /// <param name="maximum">The maximum semaphore count</param>
        /// <param name="waitThreads">Number of the threads that call Wait method</param>
        /// <param name="releaseThreads">Number of the threads that call Release method</param>
        /// <param name="succeededWait">Number of succeeded wait threads</param>
        /// <param name="failedWait">Number of failed wait threads</param>
        /// <param name="finalCount">The final semaphore count</param>
        /// <returns>True if the test succeeded, false otherwise</returns>
        private static void RunSemaphoreSlimTest8_ConcWaitAndRelease(int initial, int maximum,
            int waitThreads, int releaseThreads, int succeededWait, int failedWait, int finalCount, int timeout)
        {
            SemaphoreSlim semaphore = new SemaphoreSlim(initial, maximum);
            Task[] threads = new Task[waitThreads + releaseThreads];
            int succeeded = 0;
            int failed = 0;
            ManualResetEvent mre = new ManualResetEvent(false);
            // launch threads
            for (int i = 0; i < threads.Length; i++)
            {
                if (i < waitThreads)
                {
                    // We are creating the Task using TaskCreationOptions.LongRunning to
                    // force usage of another thread (which will be the case on the default scheduler
                    // with its current implementation).  Without this, the release tasks will likely get
                    // queued behind the wait tasks in the pool, making it very likely that the wait tasks
                    // will starve the very tasks that when run would unblock them.
                    threads[i] = new Task(delegate ()
                       {
                           mre.WaitOne();
                           if (semaphore.Wait(timeout))
                           {
                               Interlocked.Increment(ref succeeded);
                           }
                           else
                           {
                               Interlocked.Increment(ref failed);
                           }
                       }, TaskCreationOptions.LongRunning);
                }
                else
                {
                    threads[i] = new Task(delegate ()
                       {
                           mre.WaitOne();
                           semaphore.Release();
                       });
                }
                threads[i].Start(TaskScheduler.Default);
            }

            mre.Set();
            //wait work to be done;
            Task.WaitAll(threads);
            //check the number of succeeded and failed wait
            Assert.Equal(succeededWait, succeeded);
            Assert.Equal(failedWait, failed);
            Assert.Equal(finalCount, semaphore.CurrentCount);
        }
 public FakeSynchronizationService()
 {
     _semaphore = new SemaphoreSlim(1);
     _syncs     = new Dictionary <string, SemaphoreSlim>();
 }
Ejemplo n.º 53
0
        private static void TestConcurrentWaitAndWaitAsync(int syncWaiters, int asyncWaiters)
        {
            int totalWaiters = syncWaiters + asyncWaiters;

            var semaphore = new SemaphoreSlim(0);
            Task[] tasks = new Task[totalWaiters];

            const int ITERS = 10;
            int randSeed = (int)DateTime.Now.Ticks;
            for (int i = 0; i < syncWaiters; i++)
            {
                tasks[i] = Task.Run(delegate
                {
                    //Random rand = new Random(Interlocked.Increment(ref randSeed));
                    for (int iter = 0; iter < ITERS; iter++)
                    {
                        semaphore.Wait();
                        semaphore.Release();
                    }
                });
            }
            for (int i = syncWaiters; i < totalWaiters; i++)
            {
                tasks[i] = Task.Run(async delegate
                {
                    //Random rand = new Random(Interlocked.Increment(ref randSeed));
                    for (int iter = 0; iter < ITERS; iter++)
                    {
                        await semaphore.WaitAsync();
                        semaphore.Release();
                    }
                });
            }

            semaphore.Release(totalWaiters / 2);
            Task.WaitAll(tasks);
        }
Ejemplo n.º 54
0
            /// <summary>
            /// Initializes a <see cref="RateGate"/> with a rate of <paramref name="occurrences"/> 
            /// per <paramref name="timeUnit"/>.
            /// </summary>
            /// <param name="occurrences">Number of occurrences allowed per unit of time.</param>
            /// <param name="timeUnit">Length of the time unit.</param>
            /// <exception cref="ArgumentOutOfRangeException">
            /// If <paramref name="occurrences"/> or <paramref name="timeUnit"/> is negative.
            /// </exception>
            public RateGate(int occurrences, TimeSpan timeUnit)
            {
                // Check the arguments.
                if (occurrences <= 0)
                    throw new ArgumentOutOfRangeException("occurrences", "Number of occurrences must be a positive integer");
                if (timeUnit != timeUnit.Duration())
                    throw new ArgumentOutOfRangeException("timeUnit", "Time unit must be a positive span of time");
                if (timeUnit >= TimeSpan.FromMilliseconds(UInt32.MaxValue))
                    throw new ArgumentOutOfRangeException("timeUnit", "Time unit must be less than 2^32 milliseconds");

                Occurrences = occurrences;
                TimeUnitMilliseconds = (int)timeUnit.TotalMilliseconds;

                // Create the semaphore, with the number of occurrences as the maximum count.
                _semaphore = new SemaphoreSlim(Occurrences, Occurrences);

                // Create a queue to hold the semaphore exit times.
                _exitTimes = new ConcurrentQueue<int>();

                // Create a timer to exit the semaphore. Use the time unit as the original
                // interval length because that's the earliest we will need to exit the semaphore.
                _exitTimer = new Timer(ExitTimerCallback, null, TimeUnitMilliseconds, -1);
            }