try {}
finally {
Interlocked.Add (ref rwlock, RwRead);
- ctstate.LockState ^= LockState.Read;
+ ctstate.LockState |= LockState.Read;
++ctstate.ReaderRecursiveCount;
+ success = true;
}
return true;
TryEnterReadLock (ComputeTimeout (millisecondsTimeout, start), ref success);
} finally {
if (success) {
- ctstate.LockState = LockState.Upgradable;
+ ctstate.LockState |= LockState.Upgradable;
+ ctstate.LockState &= ~LockState.Read;
--ctstate.ReaderRecursiveCount;
++ctstate.UpgradeableRecursiveCount;
} else {
upgradableTaken.Value = false;
upgradableEvent.Set ();
- ctstate.LockState ^= LockState.Upgradable;
+ ctstate.LockState &= ~LockState.Upgradable;
if (Interlocked.Add (ref rwlock, -RwRead) >> RwReadBit == 0)
readerDoneEvent.Set ();
}
}
+
}
public void Dispose ()
// Detect and prevent recursion
LockState ctstate = state.LockState;
- if (ctstate != LockState.None && noRecursion && (ctstate != LockState.Upgradable || validState == LockState.Upgradable))
+ if (ctstate != LockState.None && noRecursion && (!ctstate.Has (LockState.Upgradable) || validState == LockState.Upgradable))
throw new LockRecursionException ("The current thread has already a lock and recursion isn't supported");
if (noRecursion)
Assert.AreEqual (2, v.RecursiveUpgradeCount);
}
+ [Test]
+ public void RecursiveWriteUpgradeReadTest ()
+ {
+ var rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+
+ rwlock.EnterWriteLock ();
+ Assert.IsTrue (rwlock.IsWriteLockHeld);
+ rwlock.EnterUpgradeableReadLock ();
+ Assert.IsTrue (rwlock.IsUpgradeableReadLockHeld);
+ rwlock.EnterReadLock ();
+ Assert.IsTrue (rwlock.IsReadLockHeld);
+ rwlock.ExitUpgradeableReadLock();
+ Assert.IsFalse (rwlock.IsUpgradeableReadLockHeld);
+ Assert.IsTrue (rwlock.IsReadLockHeld);
+ Assert.IsTrue (rwlock.IsWriteLockHeld);
+
+ rwlock.ExitReadLock ();
+ Assert.IsTrue (rwlock.IsWriteLockHeld);
+ }
+
+ [Test]
+ 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);
+ }
+
[Test]
public void RecursiveWriteReadAcquisitionInterleaving ()
{