public WriteLock(ReaderWriterLockSlim rwl, int millisecondsTimeout) : base(rwl) { if (millisecondsTimeout == Timeout.Infinite) { while (!_lockAcquired) _lockAcquired = rwl.TryEnterWriteLock(1); } else { _lockAcquired = rwl.TryEnterWriteLock(millisecondsTimeout); } }
/// <summary> /// The get write lock. /// </summary> /// <param name="locks"> The locks. </param> public static void GetWriteLock(ReaderWriterLockSlim locks) { bool lockAcquired = false; while (!lockAcquired) { lockAcquired = locks.TryEnterWriteLock(1); } }
public WriteLock(ReaderWriterLockSlim @lock, int millisecondsTimeout) { _lock = @lock; _isDisposed = 0; if (!_lock.TryEnterWriteLock(millisecondsTimeout)) throw new TimeoutException(); }
public void UptoVisibleQueue(ref VisibleNode root) { VisibleQueueStatus status = this.CurrentQueueStatus; if (status == VisibleQueueStatus.WaitChange) { if (m_ReadWriterLock.TryEnterWriteLock(_lockLimitMiliTime)) { try { m_VisibleQueueStatus = VisibleQueueStatus.WaitQuery; root = m_ChgVisibleQueue; m_ChgVisibleQueue = null; } finally { m_ReadWriterLock.ExitWriteLock(); } } } }
public SlimWriteLockHolder(ReaderWriterLockSlim locker, bool waitForLock) { this.locker = locker; if(waitForLock) { locker.EnterWriteLock(); lockAcquired = true; return; } lockAcquired = locker.TryEnterWriteLock(0); }
/// <summary> /// Lock our inventory list for writing (many can read, one can write) /// </summary> public void LockItemsForWrite(bool locked) { if (locked) { //Enter a write lock, wait indefinately for one to open. if (m_itemLock.RecursiveReadCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); m_itemLock.ExitReadLock(); } if (m_itemLock.RecursiveWriteCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); m_itemLock.ExitWriteLock(); } while (!m_itemLock.TryEnterWriteLock(60000)) { if (m_itemLock.IsWriteLockHeld) { m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("Locker's call stack:\n" + WriterStack); // System.Console.WriteLine("------------------------------------------"); } else { m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); // System.Console.WriteLine("------------------------------------------"); // foreach (KeyValuePair<Thread, string> kvp in ReadLockers) // { // System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); // System.Console.WriteLine("------------------------------------------"); // } } m_itemLock = new System.Threading.ReaderWriterLockSlim(); // ReadLockers.Clear(); } LockedByThread = Thread.CurrentThread; // WriterStack = Environment.StackTrace; } else { if (m_itemLock.RecursiveWriteCount > 0) { m_itemLock.ExitWriteLock(); } } }
public void CantAqureLock() { var l = new ReaderWriterLockSlim(); var e = new AutoResetEvent(false); var t = new Thread(() => { var b =l.TryEnterWriteLock(TimeSpan.FromSeconds(1)); Assert.IsTrue(b); e.Set(); Thread.Sleep(TimeSpan.FromMinutes(10)); l.Dispose(); }); t.Start(); e.WaitOne(); var a = new DisposableReaderWriterLockSlim(l, TimeSpan.FromSeconds(3), SlimLockMode.Write); }
public static void Dispose() { ReaderWriterLockSlim rwls; rwls = new ReaderWriterLockSlim(); rwls.Dispose(); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterReadLock(0)); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0)); Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterWriteLock(0)); rwls.Dispose(); for (int i = 0; i < 3; i++) { rwls = new ReaderWriterLockSlim(); switch (i) { case 0: rwls.EnterReadLock(); break; case 1: rwls.EnterUpgradeableReadLock(); break; case 2: rwls.EnterWriteLock(); break; } Assert.Throws<SynchronizationLockException>(() => rwls.Dispose()); } }
public void TryEnterWriteLock_OutOfRange () { var v = new ReaderWriterLockSlim (); try { v.TryEnterWriteLock (-2); Assert.Fail ("1"); } catch (ArgumentOutOfRangeException) { } try { v.TryEnterWriteLock (TimeSpan.MaxValue); Assert.Fail ("2"); } catch (ArgumentOutOfRangeException) { } try { v.TryEnterWriteLock (TimeSpan.MinValue); Assert.Fail ("3"); } catch (ArgumentOutOfRangeException) { } }
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(); } }
public static void ReleaseReadersWhenWaitingWriterTimesOut() { using (var rwls = new ReaderWriterLockSlim()) { // Enter the read lock rwls.EnterReadLock(); // Typical order of execution: 0 Thread writeWaiterThread; using (var beforeTryEnterWriteLock = new ManualResetEvent(false)) { writeWaiterThread = new Thread(() => { // Typical order of execution: 1 // Add a writer to the wait list for enough time to allow successive readers to enter the wait list while this // writer is waiting beforeTryEnterWriteLock.Set(); if (rwls.TryEnterWriteLock(1000)) { // The typical order of execution is not guaranteed, as sleep times are not guaranteed. For // instance, before this write lock is added to the wait list, the two new read locks may be // acquired. In that case, the test may complete before or while the write lock is taken. rwls.ExitWriteLock(); } // Typical order of execution: 4 }); writeWaiterThread.IsBackground = true; writeWaiterThread.Start(); beforeTryEnterWriteLock.WaitOne(); } Thread.Sleep(500); // wait for TryEnterWriteLock to enter the wait list // A writer should now be waiting, add readers to the wait list. Since a read lock is still acquired, the writer // should time out waiting, then these readers should enter and exit the lock. ThreadStart EnterAndExitReadLock = () => { // Typical order of execution: 2, 3 rwls.EnterReadLock(); // Typical order of execution: 5, 6 rwls.ExitReadLock(); }; var readerThreads = new Thread[] { new Thread(EnterAndExitReadLock), new Thread(EnterAndExitReadLock) }; foreach (var readerThread in readerThreads) { readerThread.IsBackground = true; readerThread.Start(); } foreach (var readerThread in readerThreads) { readerThread.Join(); } rwls.ExitReadLock(); // Typical order of execution: 7 writeWaiterThread.Join(); } }
public void RecursiveWriteLockTest () { var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion); Assert.IsTrue (v.TryEnterWriteLock (100), "#1"); Assert.IsTrue (v.TryEnterWriteLock (100), "#2"); Assert.IsTrue (v.TryEnterWriteLock (100), "#3"); Assert.AreEqual (3, v.RecursiveWriteCount); }
public static void InvalidTimeouts() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(-2)); Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(-3)); Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(-4)); Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(TimeSpan.MaxValue)); Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(TimeSpan.MinValue)); Assert.Throws<ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(TimeSpan.FromMilliseconds(-2))); } }
/// <summary> /// /// </summary> /// <param name="readerWriterLockSlim"></param> /// <returns></returns> public static bool QuickTryEnterWriteLock( ReaderWriterLockSlim readerWriterLockSlim ) { return readerWriterLockSlim.TryEnterWriteLock( s_TimeSpan ); }
/// <summary> /// Acquires a write lock on a lock object. If the lock object already holds a write /// lock, no new lock is acquired and no lock will be released. /// </summary> /// <param name="rwlock">Lock object to work with. If this is null, no lock will be acquired.</param> public WriteLock(ReaderWriterLockSlim rwlock) { this.rwlock = rwlock; if (rwlock == null) wasLocked = true; else wasLocked = rwlock.IsWriteLockHeld; if (!wasLocked && !rwlock.TryEnterWriteLock(WriteLockTimeout)) { throw new InvalidOperationException("The writer lock could not be acquired."); } }
public void TryEnterWriteLock_WhileReading () { var v = new ReaderWriterLockSlim (); AutoResetEvent ev = new AutoResetEvent (false); AutoResetEvent ev2 = new AutoResetEvent (false); Thread t1 = new Thread (() => { v.EnterReadLock (); ev2.Set (); ev.WaitOne (); v.ExitReadLock (); }); t1.Start (); ev2.WaitOne (); Assert.IsFalse (v.TryEnterWriteLock (100)); Assert.IsFalse (v.TryEnterReadLock (100)); ev.Set (); Assert.IsTrue (v.TryEnterWriteLock (100)); }
public void EnterWriteLock_After_ExitUpgradeableReadLock () { var v = new ReaderWriterLockSlim (); v.EnterUpgradeableReadLock (); Assert.IsTrue (v.TryEnterWriteLock (100)); v.ExitWriteLock (); v.ExitUpgradeableReadLock (); Assert.IsTrue (v.TryEnterWriteLock (100)); v.ExitWriteLock (); }
public static void WritersAreMutuallyExclusiveFromWriters() { using (Barrier barrier = new Barrier(2)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Task.WaitAll( Task.Run(() => { rwls.EnterWriteLock(); barrier.SignalAndWait(); Assert.True(rwls.IsWriteLockHeld); barrier.SignalAndWait(); rwls.ExitWriteLock(); }), Task.Run(() => { barrier.SignalAndWait(); Assert.False(rwls.TryEnterWriteLock(0)); Assert.False(rwls.IsReadLockHeld); barrier.SignalAndWait(); })); } }
public void RecursiveWritePlusReadLockTest () { var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion); Assert.IsTrue (v.TryEnterWriteLock (100), "#1"); Assert.AreEqual (1, v.RecursiveWriteCount, "1b"); Assert.AreEqual (0, v.RecursiveReadCount, "1c"); Assert.IsTrue (v.TryEnterReadLock (100), "#2"); Assert.AreEqual (1, v.RecursiveWriteCount, "2b"); Assert.AreEqual (1, v.RecursiveReadCount, "2c"); Assert.IsTrue (v.TryEnterReadLock (100), "#3"); Assert.AreEqual (1, v.RecursiveWriteCount, "3b"); Assert.AreEqual (2, v.RecursiveReadCount, "3c"); v.ExitReadLock (); Assert.AreEqual (1, v.RecursiveWriteCount, "4b"); Assert.AreEqual (1, v.RecursiveReadCount, "4c"); }
public static void WriterToWriterChain() { using (AutoResetEvent are = new AutoResetEvent(false)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterWriteLock(); Task t = Task.Factory.StartNew(() => { Assert.False(rwls.TryEnterWriteLock(10)); Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterWriteLock, but it's a benign race in that the test will succeed either way rwls.EnterWriteLock(); rwls.ExitWriteLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); are.WaitOne(); rwls.ExitWriteLock(); t.GetAwaiter().GetResult(); } }