public TryEnterReadLock ( TimeSpan timeout ) : bool | ||
timeout | TimeSpan | |
return | bool |
public ReadOnlyLock(ReaderWriterLockSlim rwl, int millisecondsTimeout) : base(rwl) { if (millisecondsTimeout == Timeout.Infinite) { while (!_lockAcquired) _lockAcquired = rwl.TryEnterReadLock(1); } else { _lockAcquired = rwl.TryEnterReadLock(millisecondsTimeout); } }
public ReadLock(ReaderWriterLockSlim @lock, int millisecondsTimeout) { _lock = @lock; _isDisposed = 0; if (!_lock.TryEnterReadLock(millisecondsTimeout)) throw new TimeoutException(); }
/// <summary> /// The get read only lock. /// </summary> /// <param name="locks"> The locks. </param> public static void GetReadOnlyLock(ReaderWriterLockSlim locks) { bool lockAcquired = false; while (!lockAcquired) { lockAcquired = locks.TryEnterReadLock(1); } }
public SlimReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock) { this.locker = locker; if(waitForLock) { locker.EnterReadLock(); lockAcquired = true; return; } lockAcquired = locker.TryEnterReadLock(0); }
/// <summary> /// Scope lock pattern that lock the current <see cref="ReaderWriterLockSlim"/> in read mode /// </summary> public static IDisposable LockRead(this ReaderWriterLockSlim locker, TimeSpan timeout = default(TimeSpan)) { if (timeout == default(TimeSpan)) { timeout = s_defaultTimeout; } var isLocked = locker.TryEnterReadLock(timeout); if (isLocked) { return(new ScopeLockAction <ReaderWriterLockSlim>(l => l.ExitReadLock(), locker)); } return(Disposable.Disposed); }
public void TryEnterReadLock_OutOfRange () { var v = new ReaderWriterLockSlim (); try { v.TryEnterReadLock (-2); Assert.Fail ("1"); } catch (ArgumentOutOfRangeException) { } try { v.TryEnterReadLock (TimeSpan.MaxValue); Assert.Fail ("2"); } catch (ArgumentOutOfRangeException) { } try { v.TryEnterReadLock (TimeSpan.MinValue); Assert.Fail ("3"); } catch (ArgumentOutOfRangeException) { } }
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 static void WritersAreMutuallyExclusiveFromReaders() { 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.TryEnterReadLock(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 void RecursiveReadLockTest () { var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion); Assert.IsTrue (v.TryEnterReadLock (100), "#1"); Assert.IsTrue (v.TryEnterReadLock (100), "#2"); Assert.IsTrue (v.TryEnterReadLock (100), "#3"); Assert.AreEqual (3, v.RecursiveReadCount); }
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 RecursiveWriteReadAcquisitionInterleaving() { var v = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); v.EnterWriteLock(); Assert.IsTrue(v.IsWriteLockHeld, "#1"); bool result = true; var t = new Thread(delegate () { result = v.TryEnterReadLock(100); }); t.Start(); t.Join(); Assert.IsFalse(result, "#2"); v.ExitWriteLock(); t = new Thread(delegate () { result = v.TryEnterReadLock(100); }); t.Start(); t.Join(); Assert.IsTrue(result, "#3"); }
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 WriterToReaderChain() { using (AutoResetEvent are = new AutoResetEvent(false)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterWriteLock(); Task t = Task.Factory.StartNew(() => { Assert.False(rwls.TryEnterReadLock(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.EnterReadLock(); rwls.ExitReadLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); are.WaitOne(); rwls.ExitWriteLock(); t.GetAwaiter().GetResult(); } }
/// <summary> /// Acquires a read lock on a lock object. If the lock object already holds a read /// 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 ReadLock(ReaderWriterLockSlim rwlock) { this.rwlock = rwlock; if (rwlock == null) wasLocked = true; else wasLocked = rwlock.IsReadLockHeld || rwlock.IsUpgradeableReadLockHeld || rwlock.IsWriteLockHeld; if (!wasLocked && !rwlock.TryEnterReadLock(ReadLockTimeout)) { throw new InvalidOperationException("The reader lock could not be acquired."); } }
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> /// Lock our inventory list for reading (many can read, one can write) /// </summary> public void LockItemsForRead(bool locked) { if (locked) { if (m_itemLock.IsWriteLockHeld && LockedByThread != null) { if (!LockedByThread.IsAlive) { //Locked by dead thread, reset. m_itemLock = new System.Threading.ReaderWriterLockSlim(); } } 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."); try { // That call stack is useful for end users only. RealProgrammers need a full dump. Commented. // StackTrace stackTrace = new StackTrace(); // get call stack // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) // // // write call stack method names // foreach (StackFrame stackFrame in stackFrames) // { // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name // } // The below is far more useful // 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("------------------------------------------"); // } } catch { } 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."); // try // { // 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("------------------------------------------"); // } // catch // {} m_itemLock.ExitWriteLock(); } while (!m_itemLock.TryEnterReadLock(60000)) { m_log.Error("Thread lock detected while trying to aquire READ 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."); //if (m_itemLock.IsWriteLockHeld) //{ m_itemLock = new System.Threading.ReaderWriterLockSlim(); // 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("------------------------------------------"); // LockedByThread = null; // ReadLockers.Clear(); //} } // ReadLockers[Thread.CurrentThread] = Environment.StackTrace; } else { if (m_itemLock.RecursiveReadCount > 0) { m_itemLock.ExitReadLock(); } // if (m_itemLock.RecursiveReadCount == 0) // ReadLockers.Remove(Thread.CurrentThread); } }
/// <summary> /// /// </summary> /// <param name="readerWriterLockSlim"></param> /// <returns></returns> public static bool QuickTryEnterReadLock( ReaderWriterLockSlim readerWriterLockSlim ) { return readerWriterLockSlim.TryEnterReadLock( s_TimeSpan ); }