public void TestOneReader()
        {
            AsyncUpgradeableReaderWriterLock rwLock = new AsyncUpgradeableReaderWriterLock();

            using (CancellationTokenSource readLockExit = new CancellationTokenSource())
                using (ManualResetEventSlim setWhenReadLockHeld = new ManualResetEventSlim(initialState: false))
                {
                    try
                    {
                        Task readLockHold = HoldReadLockAsync(rwLock, setWhenReadLockHeld, readLockExit.Token);
                        setWhenReadLockHeld.Wait();

                        // 1 reader -> enter reader should not be contended
                        AssertReadLockUncontended(rwLock);

                        // 1 reader -> enter upgradeable should not be contended
                        AssertUpgradeableLockUncontended(rwLock);

                        // 1 reader -> upgrading upgradeable lock should be contended
                        AssertUpgradeableLockUpgradeContended(rwLock);

                        // 1 reader -> enter writer should be contended
                        AssertWriteLockContended(rwLock);
                    }
                    finally
                    {
                        readLockExit.Cancel();
                    }
                }
        }
        public void TestUpgradeable()
        {
            AsyncUpgradeableReaderWriterLock rwLock = new AsyncUpgradeableReaderWriterLock();

            using (CancellationTokenSource upgradeableLockExit = new CancellationTokenSource())
                using (ManualResetEventSlim setWhenUpgradeableLockHeld = new ManualResetEventSlim(initialState: false))
                {
                    try
                    {
                        Task upgradeableLockHold = HoldUpgradeableLockAsync(rwLock, setWhenUpgradeableLockHeld, upgradeableLockExit.Token);
                        setWhenUpgradeableLockHeld.Wait();

                        // upgradeable -> enter reader should not be contended
                        AssertReadLockUncontended(rwLock);

                        // upgradeable -> enter upgradeable should be contended
                        AssertUpgradeableLockContended(rwLock);

                        // upgradeable -> enter writer should be contended
                        AssertWriteLockContended(rwLock);

                        // exit upgradeable lock that is in background task
                        upgradeableLockExit.Cancel();
                        upgradeableLockHold.Wait();

                        // enter upgradeable lock in foreground and try to upgrade, which should not be contended
                        AssertUpgradeableLockUpgradeUncontended(rwLock);
                    }
                    finally
                    {
                        upgradeableLockExit.Cancel();
                    }
                }
        }
 private void AssertWriteLockContended(AsyncUpgradeableReaderWriterLock rwLock)
 {
     using (CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromMilliseconds(200)))
     {
         Assert.Throws <TaskCanceledException>(() => rwLock.EnterWriteLockAsync(timeout.Token).ConfigureAwait(false).GetAwaiter().GetResult());
     }
 }
 private void AssertUpgradeableLockUncontended(AsyncUpgradeableReaderWriterLock rwLock)
 {
     using (CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromMilliseconds(200)))
         using (rwLock.EnterUpgradeableReadLockAsync(timeout.Token).ConfigureAwait(false).GetAwaiter().GetResult())
         {
             ;
         }
 }
 private void AssertReadLockUncontended(AsyncUpgradeableReaderWriterLock rwLock)
 {
     using (CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromMilliseconds(200)))
         // Will throw an OperationCanceledException if unable to get the lock within 200 ms
         using (rwLock.EnterReadLockAsync(timeout.Token).ConfigureAwait(false).GetAwaiter().GetResult())
         {
             ;
         }
 }
 private Task HoldWriteLockAsync(AsyncUpgradeableReaderWriterLock rwLock, ManualResetEventSlim setWhenLockHeld, CancellationToken cancellationToken)
 {
     return(Task.Run(() =>
     {
         using (rwLock.EnterWriteLockAsync(CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult())
         {
             setWhenLockHeld.Set();
             cancellationToken.WaitHandle.WaitOne();
         }
     }));
 }
Beispiel #7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="trainingDataLoaderFactory">Must be thread-safe.</param>
 public RecServiceState(IMalTrainingDataLoaderFactory trainingDataLoaderFactory, MalTrainingData trainingData, IDictionary <int, IList <int> > prereqs)
 {
     m_trainingDataLoaderFactory = trainingDataLoaderFactory;
     JsonRecSourceTypes          = GetJsonRecSourceTypes();
     m_trainingData               = trainingData;
     m_usernames                  = GetUsernamesFromTrainingData(m_trainingData);
     m_animes                     = m_trainingData.Animes;
     m_prereqs                    = prereqs;
     m_trainingDataLockAsync      = new AsyncUpgradeableReaderWriterLock();
     m_recSourcesLockAsync        = new AsyncUpgradeableReaderWriterLock();
     m_pendingRecSourcesLockAsync = new AsyncUpgradeableReaderWriterLock();
 }
        public void TestEmptyState()
        {
            AsyncUpgradeableReaderWriterLock rwLock = new AsyncUpgradeableReaderWriterLock();

            // No readers/writers -> enter reader should not be contended
            AssertReadLockUncontended(rwLock);

            // No readers/writers -> enter upgradeable and upgrading should not be contended
            AssertUpgradeableLockUncontended(rwLock);
            AssertUpgradeableLockUpgradeUncontended(rwLock);

            // No readers/writers -> enter writer should not be contended
            AssertWriteLockUncontended(rwLock);
        }