public bool CanAgentEnter(int id, Point3 pos, bool finalDestination) { _threadLock.EnterUpgradeableReadLock(); if (!_cells.TryGetValue(pos, out var cell) || !cell.IsWalkable) { _threadLock.ExitUpgradeableReadLock(); return(false); } if (cell.IsOccupied && cell.Occupied == id) { _threadLock.ExitUpgradeableReadLock(); return(true); } if (finalDestination && cell.IsOccupied && cell.Occupied != id) { _threadLock.ExitUpgradeableReadLock(); return(false); } if (cell.IsTempLocked && cell.TempLock != id) { _threadLock.ExitUpgradeableReadLock(); return(false); } _threadLock.EnterWriteLock(); cell.TempLock = id; SetCellCostInternal(cell); _threadLock.ExitWriteLock(); _threadLock.ExitUpgradeableReadLock(); return(true); }
private HttpStatusCode CancelCrossing(CrossingRequest cross) { m_crossLock.EnterUpgradeableReadLock(); try { if (m_crossings.ContainsKey(cross.uuid)) { m_crossLock.EnterWriteLock(); try { m_crossings.Remove(cross.uuid); return(HttpStatusCode.OK); } finally { m_crossLock.ExitWriteLock(); } } else { return(HttpStatusCode.NotFound); } } finally { m_crossLock.ExitUpgradeableReadLock(); } }
internal PacketReceiver(string LocalAddress) : base (LocalAddress) { packetReceiver = new Queue(); tokenSource = new CancellationTokenSource(); readerWriterLock = new ReaderWriterLockSlim(); tokenSource.Token.Register(() => { // Clear on cancel packetReceiver.Clear(); }); var thReceiveQueue = Task.Factory.StartNew(() => { while (tokenSource.Token.IsCancellationRequested == false) { readerWriterLock.EnterUpgradeableReadLock(); if (packetReceiver.Count > 0) { readerWriterLock.EnterWriteLock(); byte[] data = (byte[])packetReceiver.Dequeue(); readerWriterLock.ExitWriteLock(); if (OnNewPacketReceived != null) OnNewPacketReceived(this, new NewPacketEventArgs(data)); } readerWriterLock.ExitUpgradeableReadLock(); } }); }
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 int RemoveAll(Predicate <TValue> predicate) { IList <TKey1> list = new List <TKey1>(); rwLock.EnterUpgradeableReadLock(); try { foreach (var kvp in Dictionary1) { if (predicate(kvp.Value)) { list.Add(kvp.Key); } } IList <TKey2> list2 = new List <TKey2>(list.Count); foreach (var kvp in Dictionary2) { if (predicate(kvp.Value)) { list2.Add(kvp.Key); } } rwLock.EnterWriteLock(); try { foreach (var t in list) { Dictionary1.Remove(t); } foreach (var t in list2) { Dictionary2.Remove(t); } } finally { rwLock.ExitWriteLock(); } } finally { rwLock.ExitUpgradeableReadLock(); } return(list.Count); }
public int RemoveAll(Predicate <TValue> predicate) { IList <TKey1> list = new List <TKey1>(); rwLock.EnterUpgradeableReadLock(); try { foreach (KeyValuePair <TKey1, TValue> kvp in Dictionary1) { if (predicate(kvp.Value)) { list.Add(kvp.Key); } } IList <TKey2> list2 = new List <TKey2>(list.Count); foreach (KeyValuePair <TKey2, TValue> kvp in Dictionary2) { if (predicate(kvp.Value)) { list2.Add(kvp.Key); } } rwLock.EnterWriteLock(); try { for (int i = 0; i < list.Count; i++) { Dictionary1.Remove(list[i]); } for (int i = 0; i < list2.Count; i++) { Dictionary2.Remove(list2[i]); } } finally { rwLock.ExitWriteLock(); } } finally { rwLock.ExitUpgradeableReadLock(); } return(list.Count); }
/// <summary> /// Threadeds the atomic method async. /// </summary> /// <typeparam name="TValue">The type of the value.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="TList">The type of the list.</typeparam> /// <param name="rwLock">The reader writer lock.</param> /// <param name="list">The list.</param> /// <param name="key">The key.</param> /// <param name="method">The method.</param> /// <param name="contention">The contention.</param> /// <returns></returns> public static TValue ThreadedAtomicMethodAsync <TValue, TKey, TList>(this ReaderWriterLockSlim rwLock, TList list, TKey key, Func <TValue> method, Func <TValue> contention) where TList : IList <TKey> { rwLock.EnterUpgradeableReadLock(); try { if (!list.Contains(key)) { // set to running rwLock.EnterWriteLock(); try { if (list.Contains(key)) { return(contention()); } list.Add(key); } finally { rwLock.ExitWriteLock(); } // run queue TValue value; try { value = method(); } catch { list.Remove(key); throw; } // set to idle rwLock.EnterWriteLock(); try { //if (!list.Contains(key)) // return default(TValue); list.Remove(key); } finally { rwLock.ExitWriteLock(); } return(value); } } finally { rwLock.ExitUpgradeableReadLock(); } return(contention()); }
/// <summary> /// Threadeds the get with create. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rwLock">The reader writer lock.</param> /// <param name="value">The value.</param> /// <param name="builder">The builder.</param> /// <returns></returns> public static T ThreadedGetWithCreate <T>(this ReaderWriterLockSlim rwLock, ref T value, Func <T> builder) { rwLock.EnterUpgradeableReadLock(); try { if (value == null) { rwLock.EnterWriteLock(); try { if (value == null) { // create value = builder(); } } finally { rwLock.ExitWriteLock(); } } } finally { rwLock.ExitUpgradeableReadLock(); } return(value); }
/// <summary> /// Threadeds the remove. /// </summary> /// <typeparam name="TValue">The type of the value.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="THash">The type of the hash.</typeparam> /// <param name="rwLock">The reader writer lock.</param> /// <param name="hash">The hash.</param> /// <param name="key">The key.</param> public static void ThreadedRemove <TValue, TKey, THash>(this ReaderWriterLockSlim rwLock, THash hash, TKey key) where THash : IDictionary <TKey, TValue> { rwLock.EnterUpgradeableReadLock(); try { if (hash.ContainsKey(key)) { rwLock.EnterWriteLock(); try { if (hash.ContainsKey(key)) { // remove hash.Remove(key); } } finally { rwLock.ExitWriteLock(); } } } finally { rwLock.ExitUpgradeableReadLock(); } }
public void Dispose() { ReaderWriterLockSlim copy = Interlocked.Exchange(ref rwlock, null); if (copy == null) { return; } switch (type) { case LockType.Read: copy.ExitReadLock(); break; case LockType.UpgradeableRead: copy.ExitUpgradeableReadLock(); break; case LockType.Write: copy.ExitWriteLock(); break; } }
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); }
public void EnterUpgradeableReadLock () { var v = new ReaderWriterLockSlim (); v.EnterUpgradeableReadLock (); Assert.IsTrue (v.IsUpgradeableReadLockHeld, "A"); Assert.AreEqual (0, v.RecursiveWriteCount, "A1"); Assert.AreEqual (0, v.RecursiveReadCount, "A2"); Assert.AreEqual (1, v.RecursiveUpgradeCount, "A3"); Assert.AreEqual (0, v.WaitingReadCount, "A4"); Assert.AreEqual (0, v.WaitingUpgradeCount, "A5"); Assert.AreEqual (0, v.WaitingWriteCount, "A6"); v.ExitUpgradeableReadLock (); v.EnterUpgradeableReadLock (); Assert.IsTrue (v.IsUpgradeableReadLockHeld, "B"); Assert.AreEqual (0, v.RecursiveWriteCount, "B1"); Assert.AreEqual (0, v.RecursiveReadCount, "B2"); Assert.AreEqual (1, v.RecursiveUpgradeCount, "B3"); Assert.AreEqual (0, v.WaitingReadCount, "B4"); Assert.AreEqual (0, v.WaitingUpgradeCount, "B5"); Assert.AreEqual (0, v.WaitingWriteCount, "B6"); v.EnterReadLock (); v.ExitUpgradeableReadLock (); Assert.IsTrue (v.IsReadLockHeld, "C"); Assert.AreEqual (0, v.RecursiveWriteCount, "C1"); Assert.AreEqual (1, v.RecursiveReadCount, "C2"); Assert.AreEqual (0, v.RecursiveUpgradeCount, "C3"); Assert.AreEqual (0, v.WaitingReadCount, "C4"); Assert.AreEqual (0, v.WaitingUpgradeCount, "C5"); Assert.AreEqual (0, v.WaitingWriteCount, "C6"); v.ExitReadLock (); }
private static void LoadSingleProcessorData(WebDomainData data, String processorType, Object[] parameterArray, String source) { ProcessEachSettingToken(parameterArray); //+ var readerWriterLockSlim = new ReaderWriterLockSlim(); try { readerWriterLockSlim.EnterUpgradeableReadLock(); try { IProcessor processor = null; //+ if (RouteCache.ProcessorCache.ContainsKey(processorType)) { processor = RouteCache.ProcessorCache[processorType]; } else { readerWriterLockSlim.EnterWriteLock(); //+ try { if (!RouteCache.ProcessorCache.ContainsKey(processorType)) { processor = ProcessorActivator.Create<IProcessor>(processorType, RouteCache.ProcessorFactoryCache); if (processor == null) { throw new InvalidProcessorException(String.Format(Resource.Processor_Invalid, processorType)); } //+ RouteCache.ProcessorCache.Add(processorType, processor); } } finally { readerWriterLockSlim.ExitWriteLock(); } } if (processor == null) { return; } ProcessorData processorData; if (processor is InitProcessor) { processorData = new ProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; data.InitProcessorDataList.Add(processorData); } else if (processor is SelectionProcessor) { processorData = new ProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; data.SelectionProcessorDataList.Add(processorData); } else if (processor is OverrideProcessor) { processorData = new ProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; data.OverrideProcessorDataList.Add(processorData); } else if (processor is StateProcessor) { processorData = new ProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; data.StateProcessorDataList.Add(processorData); } else if (processor is PostRenderProcessor) { processorData = new ProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; data.PostRenderProcessorDataList.Add(processorData); } else if (processor is ErrorProcessor) { processorData = new ErrorProcessorData { ProcessorType = processorType, ParameterArray = parameterArray }; processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source; var epd = ((ErrorProcessorData)processorData); epd.Init(); data.ErrorProcessorDataList.Add(epd); } } finally { readerWriterLockSlim.ExitUpgradeableReadLock(); } } catch (Exception ex) { if (WebProcessingReportController.Reporter.Initialized) { var map = new Map(); map.Add("Section", "Processor"); map.Add("Type", processorType); map.Add("Message", ex.Message); map.Add("Exception Type", ex.GetType().FullName); //+ WebProcessingReportController.Reporter.AddMap(map); } } }
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 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(); } }
public static void DontReleaseWaitingReadersWhenThereAreWaitingWriters() { using(var rwls = new ReaderWriterLockSlim()) { rwls.EnterUpgradeableReadLock(); rwls.EnterWriteLock(); // Typical order of execution: 0 // Add a waiting writer var threads = new Thread[2]; using(var beforeEnterWriteLock = new ManualResetEvent(false)) { var thread = new Thread(() => { beforeEnterWriteLock.Set(); rwls.EnterWriteLock(); // Typical order of execution: 3 rwls.ExitWriteLock(); }); thread.IsBackground = true; thread.Start(); threads[0] = thread; beforeEnterWriteLock.WaitOne(); } // Add a waiting reader using(var beforeEnterReadLock = new ManualResetEvent(false)) { var thread = new Thread(() => { beforeEnterReadLock.Set(); rwls.EnterReadLock(); // Typical order of execution: 4 rwls.ExitReadLock(); }); thread.IsBackground = true; thread.Start(); threads[1] = thread; beforeEnterReadLock.WaitOne(); } // Wait for the background threads to block waiting for their locks Thread.Sleep(1000); // Typical order of execution: 1 rwls.ExitWriteLock(); // At this point there is still one reader and one waiting writer, so the reader-writer lock should not try to // release any of the threads waiting for a lock // Typical order of execution: 2 rwls.ExitUpgradeableReadLock(); // At this point, the waiting writer should be released, and the waiting reader should not foreach(var thread in threads) thread.Join(); // Typical order of execution: 5 } }
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 void EnterWriteLockWhileInUpgradeAndOtherWaiting () { var v = new ReaderWriterLockSlim (); var task2 = new Task(() => { v.EnterWriteLock(); v.ExitWriteLock(); }); var task1 = new Task(() => { v.EnterUpgradeableReadLock (); task2.Start (); Thread.Sleep (100); v.EnterWriteLock (); v.ExitWriteLock (); v.ExitUpgradeableReadLock (); }); task1.Start (); Assert.IsTrue (task1.Wait (500)); }
//- $LoadSingleFactoryData -// private static void LoadSingleFactoryData(WebDomainData data, String factoryType, Object[] parameterArray, Map parameterMap, String source) { var readerWriterLockSlim = new ReaderWriterLockSlim(); try { IFactory factory = null; //+ readerWriterLockSlim.EnterUpgradeableReadLock(); if (!RouteCache.HandlerFactoryCache.ContainsKey(factoryType) && !RouteCache.ProcessorFactoryCache.ContainsKey(factoryType)) { readerWriterLockSlim.EnterWriteLock(); //+ try { if (!RouteCache.HandlerFactoryCache.ContainsKey(factoryType) && !RouteCache.ProcessorFactoryCache.ContainsKey(factoryType)) { factory = ObjectCreator.CreateAs<IFactory>(factoryType); if (factory == null) { throw new InvalidFactoryException(String.Format(Resource.Factory_Invalid, factoryType)); } //+ FactoryData factoryData = FactoryData.Create(factoryType, parameterArray, parameterMap); factoryData.Source = String.IsNullOrEmpty(source) ? Info.System : source; if (factory is HandlerFactory) { data.HandlerFactoryDataList.Add(factoryData); RouteCache.HandlerFactoryCache.Add(factoryType, factory); } else if (factory is ProcessorFactory) { data.ProcessorFactoryDataList.Add(factoryData); RouteCache.ProcessorFactoryCache.Add(factoryType, factory); } } } finally { readerWriterLockSlim.ExitWriteLock(); } } } catch (Exception ex) { if (WebProcessingReportController.Reporter.Initialized) { var map = new Map(); map.Add("Section", "Factory"); map.Add("Type", factoryType); map.Add("Message", ex.Message); map.Add("Exception Type", ex.GetType().FullName); //+ WebProcessingReportController.Reporter.AddMap(map); } } finally { readerWriterLockSlim.ExitUpgradeableReadLock(); } }
private void Foo3() { var concurentDictionary = new Dictionary<int, int>(); var rwLockSlim = new ReaderWriterLockSlim(); var w = new ManualResetEvent(false); int timedCalled = 0; var threads = new List<Thread>(); int j; Lazy<int> lazy = new Lazy<int>(() => { Interlocked.Increment(ref timedCalled); return 1; }); for (int i = 0; i < Environment.ProcessorCount; i++) { threads.Add(new Thread(() => { w.WaitOne(); rwLockSlim.EnterUpgradeableReadLock(); try { if (!concurentDictionary.TryGetValue(1, out j)) { rwLockSlim.EnterWriteLock(); try { Interlocked.Increment(ref timedCalled); concurentDictionary[1] = 1; } finally { rwLockSlim.ExitWriteLock(); } } } finally { rwLockSlim.ExitUpgradeableReadLock(); } })); threads.Last().Start(); } w.Set();//release all threads to start at the same time Thread.Sleep(100); Console.WriteLine(timedCalled);// output is 1 }
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 (); }
private void ExitWriteLock(ReaderWriterLockSlim detectorLock) { detectorLock.ExitWriteLock(); detectorLock.EnterReadLock(); detectorLock.ExitUpgradeableReadLock(); detectorLock.ExitReadLock(); }
public static void ReleaseReadLock(ReaderWriterLockSlim locks) { if (locks.IsUpgradeableReadLockHeld) locks.ExitUpgradeableReadLock(); }
static void Main(string[] args) { // create the reader-writer lock ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); // create a cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create some shared data int sharedData = 0; // create an array of tasks Task[] readerTasks = new Task[5]; for (int i = 0; i < readerTasks.Length; i++) { // create a new task readerTasks[i] = new Task(() => { while (true) { // acqure the read lock rwlock.EnterReadLock(); // we now have the lock Console.WriteLine("Read lock acquired - count: {0}", rwlock.CurrentReadCount); // read the shared data Console.WriteLine("Shared data value {0}", sharedData); // wait - slow things down to make the example clear tokenSource.Token.WaitHandle.WaitOne(1000); // release the read lock rwlock.ExitReadLock(); Console.WriteLine("Read lock released - count {0}", rwlock.CurrentReadCount); // check for cancellation tokenSource.Token.ThrowIfCancellationRequested(); } }, tokenSource.Token); // start the new task readerTasks[i].Start(); } Task[] writerTasks = new Task[2]; for (int i = 0; i < writerTasks.Length; i++) { writerTasks[i] = new Task(() => { while (true) { // acquire the upgradeable lock rwlock.EnterUpgradeableReadLock(); // simulate a branch that will require a write if (true) { // acquire the write lock rwlock.EnterWriteLock(); // print out a message with the details of the lock Console.WriteLine("Write Lock acquired - waiting readers {0}, writers {1}, upgraders {2}", rwlock.WaitingReadCount, rwlock.WaitingWriteCount, rwlock.WaitingUpgradeCount); // modify the shared data sharedData++; // wait - slow down the example to make things clear tokenSource.Token.WaitHandle.WaitOne(1000); // release the write lock rwlock.ExitWriteLock(); } // release the upgradable lock rwlock.ExitUpgradeableReadLock(); // check for cancellation tokenSource.Token.ThrowIfCancellationRequested(); } }, tokenSource.Token); // start the new task writerTasks[i].Start(); } // prompt the user Console.WriteLine("Press enter to cancel tasks"); // wait for the user to press enter Console.ReadLine(); // cancel the tasks tokenSource.Cancel(); try { // wait for the tasks to complete Task.WaitAll(readerTasks); } catch (AggregateException agex) { agex.Handle(ex => true); } // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }