Exemple #1
0
        private TRead BodyReadWriteNotify <TRead>(TRead readValue, Func <TRead, TInternalCollection> write, Func <TRead, NotifyCollectionChangedEventArgs> change)
        {
            _lock?.EnterWriteLock();
            _internalCollection = write(readValue);
            var changeValue = change(readValue);

            if (changeValue != null)
            {
                OnCollectionChanged(changeValue);
            }
            _lock?.ExitWriteLock();
            _lock?.ExitUpgradeableReadLock();
            _viewChanged.InvokeAction();
            return(readValue);
        }
        public static void EnterExit()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                Assert.False(rwls.IsReadLockHeld);
                rwls.EnterReadLock();
                Assert.True(rwls.IsReadLockHeld);
                rwls.ExitReadLock();
                Assert.False(rwls.IsReadLockHeld);

                Assert.False(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.False(rwls.IsUpgradeableReadLockHeld);

                Assert.False(rwls.IsWriteLockHeld);
                rwls.EnterWriteLock();
                Assert.True(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.False(rwls.IsWriteLockHeld);

                Assert.False(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.False(rwls.IsWriteLockHeld);
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterWriteLock();
                Assert.True(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.False(rwls.IsWriteLockHeld);
                Assert.True(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.False(rwls.IsUpgradeableReadLockHeld);

                Assert.True(rwls.TryEnterReadLock(0));
                rwls.ExitReadLock();

                Assert.True(rwls.TryEnterReadLock(Timeout.InfiniteTimeSpan));
                rwls.ExitReadLock();

                Assert.True(rwls.TryEnterUpgradeableReadLock(0));
                rwls.ExitUpgradeableReadLock();

                Assert.True(rwls.TryEnterUpgradeableReadLock(Timeout.InfiniteTimeSpan));
                rwls.ExitUpgradeableReadLock();

                Assert.True(rwls.TryEnterWriteLock(0));
                rwls.ExitWriteLock();

                Assert.True(rwls.TryEnterWriteLock(Timeout.InfiniteTimeSpan));
                rwls.ExitWriteLock();
            }
        }
        /// <summary>
        /// Tries to enter the lock in upgradeable read mode, with an optional time-out.
        /// </summary>
        public static void TryUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLock, Action action, int millisecondsTimeout = Timeout.Infinite)
        {
            if (!readerWriterLock.TryEnterUpgradeableReadLock(millisecondsTimeout))
            {
                throw new TimeoutException();
            }

            try
            {
                action();
            }
            finally
            {
                readerWriterLock.ExitUpgradeableReadLock();
            }
        }
        public void RecursiveEnterExitUpgradableTest()
        {
            var v = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            v.EnterUpgradeableReadLock();
            v.EnterUpgradeableReadLock();
            v.EnterUpgradeableReadLock();

            Assert.IsTrue(v.IsUpgradeableReadLockHeld);
            Assert.AreEqual(3, v.RecursiveUpgradeCount);

            v.ExitUpgradeableReadLock();

            Assert.IsTrue(v.IsUpgradeableReadLockHeld);
            Assert.AreEqual(2, v.RecursiveUpgradeCount);
        }
        public static T UpgradableLock <T>(this ReaderWriterLockSlim readerWriterLock, Func <T> function)
        {
            readerWriterLock.EnterUpgradeableReadLock();

            try
            {
                return(function());
            }
            finally
            {
                if (readerWriterLock.IsUpgradeableReadLockHeld)
                {
                    readerWriterLock.ExitUpgradeableReadLock();
                }
            }
        }
Exemple #6
0
        internal bool ReplaceIfNeededWith(ICollection <T> items)
        {
            Lock.EnterUpgradeableReadLock();

            try {
                if (HashSet.SetEquals(items))
                {
                    return(false);
                }

                ReplaceWith(items);
                return(true);
            } finally {
                Lock.ExitUpgradeableReadLock();
            }
        }
Exemple #7
0
 public void AddVoxel(Voxel_Habitat newVoxel)
 {
     VoxelListLock.EnterUpgradeableReadLock();
     try {
         VoxelListLock.EnterWriteLock();
         try {
             voxCloud.Add(newVoxel, newVoxel.getPosition);
         }
         finally {
             VoxelListLock.ExitWriteLock();
         }
     }
     finally {
         VoxelListLock.ExitUpgradeableReadLock();
     }
 }
            public void ShouldReturnTrue_WhenUpgradeableReadLockIsHeld()
            {
                // Arrange
                var sut = new ReaderWriterLockSlim();

                sut.EnterUpgradeableReadLock();

                // Act
                bool result = sut.IsLockHeld();

                // Assert
                Assert.True(result);

                // Cleanup
                sut.ExitUpgradeableReadLock();
            }
        public void RecursiveWriteUpgradeTest()
        {
            ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            rwlock.EnterWriteLock();
            Assert.IsTrue(rwlock.IsWriteLockHeld);
            rwlock.EnterUpgradeableReadLock();
            Assert.IsTrue(rwlock.IsUpgradeableReadLockHeld);
            rwlock.ExitUpgradeableReadLock();
            Assert.IsFalse(rwlock.IsUpgradeableReadLockHeld);
            Assert.IsTrue(rwlock.IsWriteLockHeld);
            rwlock.ExitWriteLock();
            Assert.IsFalse(rwlock.IsWriteLockHeld);
            rwlock.EnterWriteLock();
            Assert.IsTrue(rwlock.IsWriteLockHeld);
        }
Exemple #10
0
 public int GetId(ACL acl)
 {
     locker.EnterUpgradeableReadLock();
     try
     {
         return(_UnsafeGetId(acl));
     }
     catch (Exception)
     {
         throw;
     }
     finally
     {
         locker.ExitUpgradeableReadLock();
     }
 }
Exemple #11
0
        internal void OrderStatusHandle(OrderStatusData data)
        {
            Guid guid = data.OrigClientId;

            _ordersLock.EnterUpgradeableReadLock();
            try
            {
                if (!_orders.ContainsKey(guid))
                {
                    if (data.Status != OrderStatus.Rejected && data.Status != OrderStatus.Canceled)
                    {
                        _ordersLock.EnterWriteLock();
                        try
                        {
                            _orders.Add(guid, data.OrderType == OrderType.Limit ?
                                        (OrderBase) new OrderLimit(data, data.Symbol) :
                                        new OrderMarket(data, data.Symbol));
                            _orders[guid].TimeStamp = data.OrderTimestamp;
                        }
                        finally
                        { _ordersLock.ExitWriteLock(); }
                    }
                }
                else
                {
                    if (data.Status == OrderStatus.Rejected || data.Status == OrderStatus.Canceled)
                    {
                        _orders[guid].TimeStamp = data.OrderTimestamp;
                        _orders[guid].Status    = data.Status;
                        _orders[guid].OrderChanged();

                        _ordersLock.EnterWriteLock();
                        try
                        {
                            _orders[guid].Dispose();
                            _orders.Remove(guid);
                        }
                        finally
                        { _ordersLock.ExitWriteLock(); }
                    }
                    else
                    {
                        _orders[guid].TimeStamp    = data.OrderTimestamp;
                        _orders[guid].OpenTime     = data.OpenTime;
                        _orders[guid].OrigClientId = data.OrigClientId;
                        _orders[guid].OrigQuantity = data.OrigQuantity;
                        _orders[guid].Status       = data.Status;

                        _orders[guid].OrderChanged();
                    }
                }
            }
            finally
            { _ordersLock.ExitUpgradeableReadLock(); }
        }
        /// <summary>
        ///   Gets the class map for the specified class type.
        /// </summary>
        /// <param name = "classType">Type of the entity.</param>
        /// <returns></returns>
        public IClassMap GetClassMap(Type classType)
        {
            try
            {
                _lock.EnterUpgradeableReadLock();

                IClassMap classMap;
                if (_autoMaps.TryGetValue(classType, out classMap))
                {
                    return(classMap);
                }

                if (_wrappedMappingStore != null)
                {
                    classMap = _wrappedMappingStore.GetClassMap(classType);
                    if (classMap != null)
                    {
                        return(classMap);
                    }
                }

                classMap = _autoMapper.CreateClassMap(classType, GetClassMap);

                try
                {
                    _lock.EnterWriteLock();

                    _autoMaps.Add(classType, classMap);

                    return(classMap);
                }
                finally
                {
                    if (_lock.IsWriteLockHeld)
                    {
                        _lock.ExitWriteLock();
                    }
                }
            }
            finally
            {
                if (_lock.IsUpgradeableReadLockHeld)
                {
                    _lock.ExitUpgradeableReadLock();
                }
            }
        }
        public TValue GetOrAdd(TKey key, Func <TKey, TValue> addFunc)
        {
            Contract.RequiresNotNull(addFunc, nameof(addFunc));

            // simple case of we already have a value for the key
            _rwLock.EnterReadLock();
            try
            {
                if (_map.TryGetValue(key, out var value))
                {
                    return(value);
                }
            }
            finally
            {
                _rwLock.ExitReadLock();
            }

            // no value for the key
            _rwLock.EnterUpgradeableReadLock();
            try
            {
                // some other thread may have just added it
                if (_map.TryGetValue(key, out var value))
                {
                    return(value);
                }

                // the function may take "some time" so evaluate it outside of the write lock so other threads can still read the dictionary
                value = addFunc(key);

                _rwLock.EnterWriteLock();
                try
                {
                    _map[key] = value;
                }
                finally
                {
                    _rwLock.ExitWriteLock();
                }
                return(value);
            }
            finally
            {
                _rwLock.ExitUpgradeableReadLock();
            }
        }
 public AddOrUpdateStatus AddOrUpdate(K key, V value)
 {
     _lock.EnterUpgradeableReadLock();
     try
     {
         //V result = null;
         V result = default(V);
         if (cacheData.TryGetValue(key, out result))
         {
             //if (result == value)
             if (result.Equals(value))
             {
                 return(AddOrUpdateStatus.Unchanged);
             }
             else
             {
                 _lock.EnterWriteLock();
                 try
                 {
                     cacheData[key] = value;
                 }
                 finally
                 {
                     _lock.ExitWriteLock();
                 }
                 return(AddOrUpdateStatus.Updated);
             }
         }
         else
         {
             _lock.EnterWriteLock();
             try
             {
                 cacheData.Add(key, value);
             }
             finally
             {
                 _lock.ExitWriteLock();
             }
             return(AddOrUpdateStatus.Added);
         }
     }
     finally
     {
         _lock.ExitUpgradeableReadLock();
     }
 }
Exemple #15
0
 public TValue this[TKey key]
 {
     get
     {
         _readerWriterLock.EnterReadLock();
         try
         {
             return(_dictionary[key]);
         }
         finally
         {
             _readerWriterLock.ExitReadLock();
         }
     }
     set
     {
         _readerWriterLock.EnterUpgradeableReadLock();
         try
         {
             var containsKey = _dictionary.ContainsKey(key);
             _readerWriterLock.EnterWriteLock();
             try
             {
                 if (containsKey)
                 {
                     _dictionary[key] = value;
                 }
                 else
                 {
                     var added = TryAdd(key, value);
                     if (!added)
                     {
                         throw new InvalidOperationException("Dictionary is at max size, can not add additional members.");
                     }
                 }
             }
             finally
             {
                 _readerWriterLock.ExitWriteLock();
             }
         }
         finally
         {
             _readerWriterLock.ExitUpgradeableReadLock();
         }
     }
 }
Exemple #16
0
        public T Read(string addr, Func <T> func)
        {
            cacheLock.EnterReadLock();
            try
            {
                IsEmpty = false;
                var o = cache[addr];
                if (o != null)
                {
                    SavedCache++;
                    return((T)o);
                }
            }
            finally
            {
                cacheLock.ExitReadLock();
            }

            cacheLock.EnterUpgradeableReadLock();

            try
            {
                var ob = cache.Get(addr);
                if (ob != null)
                {
                    SavedCache++;
                    return((T)ob);
                }

                try
                {
                    cacheLock.EnterWriteLock();
                    var tt = func();
                    FuncCache++;
                    cache.Add(addr, tt, _policy);
                    return(tt);
                }
                finally
                {
                    cacheLock.ExitWriteLock();
                }
            }
            finally
            {
                cacheLock.ExitUpgradeableReadLock();
            }
        }
Exemple #17
0
        public static void Execute()
        {
            var padLock = new ReaderWriterLockSlim();
            var random  = new Random();

            int x = 0;

            var tasks = new List <Task>();

            for (var i = 0; i < 10; i++)
            {
                var taskNum = i;
                tasks.Add(Task.Factory.StartNew(() =>
                {
                    padLock.EnterUpgradeableReadLock();
                    Console.WriteLine($"Entered read lock, x = {x}");

                    if (taskNum % 2 == 1)
                    {
                        padLock.EnterWriteLock();
                        x = random.Next(10);
                        Console.WriteLine($"Set {x}");
                        padLock.ExitWriteLock();
                    }

                    Thread.Sleep(2000);

                    padLock.ExitUpgradeableReadLock();
                    Console.WriteLine($"Exited read lock, x = {x}");
                }));
            }

            try
            {
                Task.WaitAll(tasks.ToArray());
            }
            catch (AggregateException ae)
            {
                ae.Handle(e =>
                {
                    Console.WriteLine(e);
                    return(true);
                });
            }

            Console.WriteLine("The end");
        }
        public TIMyDuck GenerateProxy <TIMyDuck>(object otherDuck) where TIMyDuck : class
        {
            Type typeOfIMyDuck = typeof(TIMyDuck);

            ValidateParams(typeOfIMyDuck, otherDuck);

            //If obj already implements TProxy, simply return it
            TIMyDuck o = otherDuck as TIMyDuck;

            if (o != null)
            {
                return(o);
            }

            Type proxyType       = null;
            Type typeOfOtherDuck = otherDuck.GetType();

            _cacheLock.EnterUpgradeableReadLock();
            try
            {
                if (!_typeCache.TryGetValue(new Tuple <Type, Type>(typeOfIMyDuck, typeOfOtherDuck), out proxyType))
                {
                    //Generate the proxyType here
                    if (!CanBeDuckTypedTo <TIMyDuck>(otherDuck))
                    {
                        throw new ArgumentException("Object cannot be duck typed by the interface.");
                    }

                    proxyType = GenerateProxyType(typeOfIMyDuck, otherDuck.GetType());

                    _cacheLock.EnterWriteLock();
                    try
                    {
                        _typeCache.Add(new Tuple <Type, Type>(typeOfIMyDuck, typeOfOtherDuck), proxyType);
                    }
                    finally
                    {
                        _cacheLock.ExitWriteLock();
                    }
                }
                return((TIMyDuck)Activator.CreateInstance(proxyType, otherDuck));
            }
            finally
            {
                _cacheLock.ExitUpgradeableReadLock();
            }
        }
Exemple #19
0
        T GetNode(int hash)
        {
            _lock.EnterUpgradeableReadLock();
            try
            {
                if (_circle.Keys.Count == 0)
                    return default;

                int first = FirstGreaterThanOrEqual(_keyCache.Value, hash);

                return _circle[_keyCache.Value[first]];
            }
            finally
            {
                _lock.ExitUpgradeableReadLock();
            }
        }
Exemple #20
0
        /// <summary>
        /// Creates the image transform.
        /// </summary>
        /// <param name="typeName">Name of the type.</param>
        /// <returns>An instance of the image tranform</returns>
        internal static ImageTransform Create(string typeName)
        {
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentNullException("typeName");
            }

            ImageTransform  retVal          = null;
            ConstructorInfo constructorInfo = null;

            readerWriterLockSlim.EnterUpgradeableReadLock();
            try {
                if (!imageTransformCache.TryGetValue(typeName, out constructorInfo))
                {
                    Type connectorType = Type.GetType(typeName, false, true);
                    if (connectorType != null && connectorType.IsSubclassOf(typeof(ImageTransform)))
                    {
                        constructorInfo = connectorType.GetConstructor(Type.EmptyTypes);

                        if (constructorInfo == null)
                        {
                            string errorMessage = string.Format(CultureInfo.InvariantCulture, "The given type: '{0}' does not contain a constructor that takes no arguments.", typeName);
                            throw new ArgumentException(errorMessage, "typeName");
                        }

                        readerWriterLockSlim.EnterWriteLock();
                        try {
                            imageTransformCache.Add(typeName, constructorInfo);
                        } finally {
                            readerWriterLockSlim.ExitWriteLock();
                        }
                    }
                    else
                    {
                        string errorMessage = string.Format(CultureInfo.InvariantCulture, "The given type: '{0}' can not be found or does not implement the abstract ImageTransform class.", typeName);
                        throw new ArgumentException(errorMessage, "typeName");
                    }
                }
            } finally {
                readerWriterLockSlim.ExitUpgradeableReadLock();
            }

            retVal = constructorInfo.Invoke(null) as ImageTransform;

            return(retVal);
        }
            public void Dispose()
            {
                switch (lockType)
                {
                case LockType.Read:
                    readerWriterLock.ExitReadLock();
                    break;

                case LockType.Write:
                    readerWriterLock.ExitWriteLock();
                    break;

                case LockType.Upgradeable:
                    readerWriterLock.ExitUpgradeableReadLock();
                    break;
                }
            }
Exemple #22
0
        void IDisposable.Dispose()
        {
            switch (_readerWriteLockType)
            {
            case ReaderWriteLockType.Read:
                _rwLock.ExitReadLock();
                break;

            case ReaderWriteLockType.Write:
                _rwLock.ExitWriteLock();
                break;

            case ReaderWriteLockType.UpgradeableRead:
                _rwLock.ExitUpgradeableReadLock();
                break;
            }
        }
Exemple #23
0
        public IAutoDetection GetAutoDetection(int configurationId)
        {
            cacheLock.EnterUpgradeableReadLock();
            try
            {
                if (!AutoDetectionPool.ContainsKey(configurationId))
                {
                    CreateAutoDetector(configurationId);
                }

                return(AutoDetectionPool[configurationId]);
            }
            finally
            {
                cacheLock.ExitUpgradeableReadLock();
            }
        }
        /// <summary>Executes <paramref name="onLockAcquired" /> after acquiring a Read Lock from <paramref name="rwLock" />, provided <paramref name="timeOut" /> is not reached waiting for lock.</summary>
        /// <param name="rwLock">The lock to acquire.</param>
        /// <param name="onLockAcquired">Delegate to execute inside of the lock boundaries.</param>
        /// <param name="timeOut">Length of time to wait to acqurie the lock</param>
        /// <returns>If the lock is acquired and <paramref name="onLockAcquired" /> is executed, returns <see langword="true" />; otherwise <see langword="false" /></returns>
        public static bool ExecuteUpgradableRead(this ReaderWriterLockSlim rwLock, Action onLockAcquired, TimeSpan timeOut)
        {
            if (!rwLock.TryEnterUpgradeableReadLock(timeOut))
            {
                return(false);
            }

            try
            {
                onLockAcquired();
                return(true);
            }
            finally
            {
                rwLock.ExitUpgradeableReadLock();
            }
        }
Exemple #25
0
 public void Dispose()
 {
     if (writerLock != null && writerLock.LockAcquired)
     {
         writerLock.Dispose();
         writerLock = null;
     }
     if (!LockAcquired)
     {
         return;
     }
     if (!wasLockAlreadyHeld)
     {
         locker.ExitUpgradeableReadLock();
     }
     lockAcquired = false;
 }
Exemple #26
0
            void IDisposable.Dispose()
            {
                switch (_Mode)
                {
                case LockMode.Write:
                    _Slim.ExitWriteLock();
                    break;

                case LockMode.Read:
                    _Slim.ExitReadLock();
                    break;

                case LockMode.UpgradeableRead:
                    _Slim.ExitUpgradeableReadLock();
                    break;
                }
            }
 static void WriteWithUpgradeableReadLock(object threadID)
 {
     while (true)
     {
         int newNumber = GetRandNum(100);
         _rw.EnterUpgradeableReadLock();                 // 可升级锁
         if (!_items.Contains(newNumber))
         {
             _rw.EnterWriteLock();                               // 可升级锁 转化 为死锁
             _items.Add(newNumber);
             _rw.ExitWriteLock();
             Console.WriteLine("Thread " + threadID + " added " + newNumber);
         }
         _rw.ExitUpgradeableReadLock();
         Thread.Sleep(100);
     }
 }
        Script /*!*/ TryGetOrCreateScript(string code, Context.ScriptOptions options, ScriptingContext context)
        {
            var script = default(Script);

            _scriptsLock.EnterUpgradeableReadLock();
            try
            {
                if (!_scripts.TryGetValue(code, out var subsmissions))
                {
                    _scriptsLock.EnterWriteLock();
                    try
                    {
                        if (!_scripts.TryGetValue(code, out subsmissions))
                        {
                            _scripts[code] = subsmissions = new List <Script>(1);
                        }
                    }
                    finally
                    {
                        _scriptsLock.ExitWriteLock();
                    }
                }

                if ((script = CacheLookupNoLock(subsmissions, options, code, context)) == null)
                {
                    _scriptsLock.EnterWriteLock();
                    try
                    {
                        if ((script = CacheLookupNoLock(subsmissions, options, code, context)) == null)
                        {
                            subsmissions.Add((script = Script.Create(options, code, _builder, context.Submissions)));
                        }
                    }
                    finally
                    {
                        _scriptsLock.ExitWriteLock();
                    }
                }
            }
            finally
            {
                _scriptsLock.ExitUpgradeableReadLock();
            }

            return(script);
        }
Exemple #29
0
        public static T UpgradableReadExecute <T>(this ReaderWriterLockSlim locker, Func <T> func)
        {
            if (func == null)
            {
                throw new ArgumentNullException(nameof(func));
            }

            try
            {
                locker.EnterUpgradeableReadLock();
                return(func());
            }
            finally
            {
                locker.ExitUpgradeableReadLock();
            }
        }
Exemple #30
0
        public void Dispose()
        {
            switch (mode)
            {
            case LockMode.Read:
                locker.ExitReadLock();
                break;

            case LockMode.Write:
                locker.ExitWriteLock();
                break;

            case LockMode.UpgradeableRead:
                locker.ExitUpgradeableReadLock();
                break;
            }
        }
Exemple #31
0
        /// <summary>
        /// 使用指定的方法进行写操作。
        /// </summary>
        /// <param name="method">一个方法,在此方法执行期间将被写锁定。</param>
        public void LockWrite(Action method)
        {
            Guard.ArgumentNull(method, nameof(method));

            var isMustReadHeld  = false;
            var isMustWriteHeld = false;
            var isUpgradeable   = false;

            if (locker.IsReadLockHeld)
            {
                locker.ExitReadLock();
                if (!locker.IsUpgradeableReadLockHeld)
                {
                    locker.EnterUpgradeableReadLock();
                    isUpgradeable = true;
                }

                isMustReadHeld = true;
            }
            else if (!locker.IsWriteLockHeld)
            {
                locker.EnterWriteLock();
                isMustWriteHeld = true;
            }

            try
            {
                method();
            }
            finally
            {
                if (isMustReadHeld)
                {
                    if (isUpgradeable)
                    {
                        locker.ExitUpgradeableReadLock();
                    }

                    locker.EnterReadLock();
                }
                else if (isMustWriteHeld)
                {
                    locker.ExitWriteLock();
                }
            }
        }
        public static void DeadlockAvoidance()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                rwls.ExitReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                rwls.EnterWriteLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitWriteLock();
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.ExitWriteLock();
            }

            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion))
            {
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock());
                rwls.EnterReadLock();
                Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock());
                rwls.ExitReadLock();
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                rwls.EnterReadLock();
                rwls.EnterUpgradeableReadLock();
                rwls.ExitUpgradeableReadLock();
                rwls.EnterReadLock();
                rwls.ExitReadLock();
                rwls.ExitReadLock();
                rwls.EnterWriteLock();
                rwls.EnterWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                rwls.EnterReadLock();
                rwls.ExitReadLock();
                rwls.EnterUpgradeableReadLock();
                rwls.ExitUpgradeableReadLock();
                rwls.EnterWriteLock();
                rwls.ExitWriteLock();
                rwls.ExitWriteLock();
            }
        }
        public static void InvalidExits(LockRecursionPolicy policy)
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(policy))
            {
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());

                rwls.EnterReadLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                rwls.ExitReadLock();

                rwls.EnterUpgradeableReadLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                rwls.ExitUpgradeableReadLock();

                rwls.EnterWriteLock();
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock());
                Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock());
                rwls.ExitWriteLock();

                using (Barrier barrier = new Barrier(2))
                {
                    Task t = Task.Factory.StartNew(() =>
                    {
                        rwls.EnterWriteLock();
                        barrier.SignalAndWait();
                        barrier.SignalAndWait();
                        rwls.ExitWriteLock();
                    }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                    barrier.SignalAndWait();
                    Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock());
                    barrier.SignalAndWait();

                    t.GetAwaiter().GetResult();
                }
            }
        }
 public static void WriterToUpgradeableReaderChain()
 {
     using (AutoResetEvent are = new AutoResetEvent(false))
     using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
     {
         rwls.EnterWriteLock();
         Task t = Task.Factory.StartNew(() =>
         {
             Assert.False(rwls.TryEnterUpgradeableReadLock(TimeSpan.FromMilliseconds(10)));
             Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterReadLock, but it's a benign race in that the test will succeed either way
             rwls.EnterUpgradeableReadLock();
             rwls.ExitUpgradeableReadLock();
         }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
         are.WaitOne();
         rwls.ExitWriteLock();
         t.GetAwaiter().GetResult();
     }
 }