public void CanAcquireAndReleaseReadLock()
        {
            var l = new ReaderWriterLockSlimEx();

            using(l.AcquireReadLock())
            {
                // access lock here so it's not optimized-away after release build
                Assert.IsNotNull(l);
            }
        }
        public void SupportsRecursion__WriteLockIsHeld__AnotherLockCanBeAcquired()
        {
            var l = new ReaderWriterLockSlimEx(LockRecursionPolicy.SupportsRecursion);

            IReadLockAcquisition r;
            IUpgradeableReadLockAcquisition ur;
            IWriteLockAcquisition w;

            var a1 = l.AcquireReadLock();
            var a2 = l.TryAcquireReadLock(TEST_DefaultTimeout, out r);
            var a3 = l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out ur);
            var a4 = l.TryAcquireWriteLock(TEST_DefaultTimeout, out w);

            Assert.IsTrue(a2);
            Assert.IsFalse(a3);
            Assert.IsFalse(a4);
        }
        public void ReadLockIsHeld__AnotherThreadBlocksOnWriteLockAcquisition()
        {
            var l = new ReaderWriterLockSlimEx();

            using (l.AcquireReadLock())
            {
                Task.Factory.StartNew(() =>
                {
                    var acquisition = (IWriteLockAcquisition)null;

                    if (l.TryAcquireWriteLock(TEST_DefaultTimeout, out acquisition))
                    {
                        // should not acquire
                        Assert.Fail();
                    }
                }).Wait();
            }
        }
        public void ReadLockIsHeld__AnotherThreadDoesNotBlockOnUpgradeableReadLockAcquisition()
        {
            var l = new ReaderWriterLockSlimEx();

            using (l.AcquireReadLock())
            {
                Task.Factory.StartNew(() =>
                {
                    var acquisition = (IUpgradeableReadLockAcquisition)null;

                    if (!l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out acquisition))
                    {
                        // should be able to acquire
                        Assert.Fail();
                    }
                }).Wait();
            }
        }
        public void ReadLockIsHeld__CannotAcquireUpgradeableReadLock()
        {
            var l = new ReaderWriterLockSlimEx();

            using (var rl = l.AcquireReadLock())
            {
                var acquisition = (IUpgradeableReadLockAcquisition)null;

                if (l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out acquisition))
                {
                    // should not get here
                    Assert.Fail();
                }
            }
        }