protected TRead DoReadWriteNotify <TRead>(Func <TRead> read, Func <TRead, TInternalCollection> write, params Func <TRead, NotifyCollectionChangedEventArgs>[] changes) { _lock?.EnterUpgradeableReadLock(); TRead readValue = read(); return(BodyReadWriteNotify(readValue, write, changes)); }
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 void RecursiveWriteUpgradeTest() { using (var 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); rwlock.ExitWriteLock(); } }
public TValue this[TKey key] { get { this.CleanCache(); try { rwLock.EnterUpgradeableReadLock(); WeakReference wr; TValue val; if (data.TryGetValue(key, out wr)) { val = (TValue)wr.Target; if (val != null) { return(val); } } try { rwLock.EnterWriteLock(); if (data.TryGetValue(key, out wr)) { val = (TValue)wr.Target; if (val != null) { return(val); } } data[key] = new WeakReference(val = getter(key)); return(val); } finally { rwLock.ExitWriteLock(); } } finally { rwLock.ExitUpgradeableReadLock(); } } }
public ReaderWriterLockScope(ReaderWriterLockSlim locker, ReaderWriterLockMode mode) { this.locker = locker; this.mode = mode; switch (mode) { case ReaderWriterLockMode.Read: locker.EnterReadLock(); break; case ReaderWriterLockMode.Write: locker.EnterWriteLock(); break; case ReaderWriterLockMode.UpgradeableRead: locker.EnterUpgradeableReadLock(); break; } }
public static IReadOnlyCollection <Assembly> GetReferencedAssemblies( ICollection <string> namespaceKeywords = null) { namespaceKeywords = new AssemblyHelperConfig().NamespaceKeywords; var domainAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(x => namespaceKeywords.Any(y => x.FullName.Contains(y))) .ToList(); domainAssemblies.Add(Assembly.GetExecutingAssembly()); Lock.EnterUpgradeableReadLock(); try { if (!ReferencedAssemblies.Any()) { Lock.EnterWriteLock(); try { var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); ReferencedAssemblies.AddRange( referencedPaths.Select( path => AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(path))) .Where(x => namespaceKeywords.Any(y => x.FullName.Contains(y)))); } finally { Lock.ExitWriteLock(); } } } finally { Lock.ExitUpgradeableReadLock(); } var allAssemblies = new List <Assembly>(domainAssemblies); allAssemblies.AddRange(ReferencedAssemblies); return(allAssemblies); }
/// <summary> /// Set a localized value into Xml source /// </summary> /// <param name="name"></param> /// <param name="value"></param> /// <param name="comment"></param> /// <param name="isApproved">boolean value for automatically created resource keys. False by default.</param> /// <returns></returns> public bool TrySetValue <TResource>(string name, string value, string comment, bool isApproved = false) where TResource : class { var _path = ResourcePath <TResource>(); var path = string.Format(_path, CultureInfo.CurrentCulture.Name); var xElement = CreateXElement(name, value, comment, isApproved); var success = false; _lock.EnterUpgradeableReadLock(); try { var _doc = GetXmlDocument(path); if (Find(name, _doc) == null) { _lock.EnterWriteLock(); try { _doc.Root.Add(xElement); _doc.Save(path); success = true; } finally { _lock.ExitWriteLock(); } _logger.LogInformation($"New key adding result: '{success}', key name: '{name}', path: '{path}'"); } } catch { value = null; } finally { _lock.ExitUpgradeableReadLock(); } return(success); }
/// <summary> /// Called by base class when it wants to dump a page of objects out of the buffer /// </summary> /// <param name="pageOfObjects"></param> protected override void OnBufferAction(List <LogMessage> pageOfObjects) { try { _initializeLock.EnterUpgradeableReadLock(); if (_logInitialized == false) { try { _initializeLock.EnterWriteLock(); if (_logInitialized == false) { _logPersister = CoreConfig.Log.ActiveDispatcher; _logPersister.Initialize(); _logInitialized = true; } } finally { _initializeLock.ExitWriteLock(); } } } finally { _initializeLock.ExitUpgradeableReadLock(); } try { _dispatcherLock.EnterWriteLock(); _logPersister.PersistMessages(pageOfObjects); pageOfObjects.Clear(); } catch (Exception ex) { LastChanceLog(ex); } finally { _dispatcherLock.ExitWriteLock(); } }
public AddOrUpdateStatus AddOrUpdate(int key, string value) { sl.EnterUpgradeableReadLock(); string val; try{ if (syncCache.TryGetValue(key, out val)) { if (val == value) { return(AddOrUpdateStatus.Unchanged); } else { sl.EnterWriteLock(); try{ syncCache[key] = value; return(AddOrUpdateStatus.Updated); } finally { sl.ExitWriteLock(); } } } else { sl.EnterWriteLock(); try{ syncCache.Add(key, value); return(AddOrUpdateStatus.Add); } finally { sl.ExitWriteLock(); } } } finally{ sl.ExitUpgradeableReadLock(); } }
public ReaderWriteLockDisposable(ReaderWriterLockSlim rwLock, ReaderWriteLockType readerWriteLockType = ReaderWriteLockType.Write) { _rwLock = rwLock; _readerWriteLockType = readerWriteLockType; switch (_readerWriteLockType) { case ReaderWriteLockType.Read: _rwLock.EnterReadLock(); break; case ReaderWriteLockType.Write: _rwLock.EnterWriteLock(); break; case ReaderWriteLockType.UpgradeableRead: _rwLock.EnterUpgradeableReadLock(); break; } }
/// <summary> /// Get a composite class from the base type, all the properties and interfaces needed /// </summary> /// <param name="baseType">Base type</param> /// <param name="properties">properties needed</param> /// <param name="interfaces">interfaces needed</param> /// <returns>Dynamically built composite type</returns> public Type GetCompositeClass(Dictionary <Type, TypeBuilder> typeBuilders, Type baseType, IEnumerable <DynamicProperty> properties, IEnumerable <Type> interfaces) { rwLock.EnterUpgradeableReadLock(); try { Signature signature = new Signature(properties); Type type; //if (!classes.TryGetValue(signature, out type)) //{ type = CreateDynamicClass(typeBuilders, baseType, signature.properties, interfaces); // classes.Add(signature, type); //} return(type); } finally { rwLock.ExitUpgradeableReadLock(); } }
internal TransientModule GetModule(ScriptContext /*!*/ context, DTypeDesc caller, string /*!*/ code, SourceCodeDescriptor descriptor) { Debug.Assert(context != null && code != null); Key key = new Key(code, descriptor); Value value; rwLock.EnterUpgradeableReadLock(); try { if (cache.TryGetValue(key, out value)) { if (TypesProvider.LoadAndMatch(value.TypeDependencies, context, caller)) { #if !SILVERLIGHT Performance.Increment(Performance.DynamicCacheHits); #endif return(value.Module); } else { // invalidate the cache entry, because type dependencies were changed: rwLock.EnterWriteLock(); try { cache.Remove(key); } finally { rwLock.ExitWriteLock(); } } } } finally { rwLock.ExitUpgradeableReadLock(); } return(null); }
public SlimUpgradeableReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock, bool wasLockAlreadyHelf) { this.locker = locker; if (wasLockAlreadyHelf) { lockAcquired = true; wasLockAlreadyHeld = true; return; } if (waitForLock) { locker.EnterUpgradeableReadLock(); lockAcquired = true; return; } lockAcquired = locker.TryEnterUpgradeableReadLock(0); }
public T ReadValue <T>(string valName, T def) { T val = def; _locker.EnterUpgradeableReadLock(); try { if (!GetFromCache(valName, out val)) { var configPath = ConfigPath; _locker.EnterWriteLock(); try { using (var cf = new ConfigFile(configPath)) { if (!cf.Contains(valName)) { cf.Add(valName, def); cf.Save(); val = def; } else { if (!cf.Get(valName, out val)) { val = def; } } } AddToCache(valName, val); } catch (Exception e) { Log.Error("ReadValue", e); } finally { _locker.ExitWriteLock(); } } } catch (Exception e) { Log.Error("ReadValue", e); } finally { _locker.ExitUpgradeableReadLock(); } return(val); }
/// <summary> /// Uses the provided key to lookup data in the <see cref="Cache{TItem, UKey, VData}"/> and returns it /// </summary> /// <param name="key">The key used to lookup data in the <see cref="Cache{TItem, UKey, VData}"/></param> /// <returns>If the key is found, returns the data associated with it, otherwise <c>default(U)</c></returns> public VData Get(UKey key) { // if disposed, throw exception EnsureNotDisposed(); int startIndex = GetStartIndexFromKey(key); int endIndex = startIndex + _numEntry - 1; VData ans = default(VData); // need a readLock cacheLock.EnterUpgradeableReadLock(); try { for (int i = startIndex; i <= endIndex; i++) { if (_cacheArray[i] == default(TItem) || _cacheArray[i] == null || _cacheArray[i].IsEmpty) { continue; } if (((IEquatable <UKey>)_cacheArray[i].Key).Equals(key)) { ans = _cacheArray[i].Data; // if this cache implements IOnAccessCacheEntry, // then we need to indicate we accessed this item if (_isOnAccessCacheEntry) { cacheLock.EnterWriteLock(); try { ((IOnAccessCacheEntry)_cacheArray[i]).OnDataAccess(); } finally { cacheLock.ExitWriteLock(); } } } } } finally { cacheLock.ExitUpgradeableReadLock(); } return(ans); }
public T ReadValue <T>(string valName, T def) { T val; try { locker.EnterUpgradeableReadLock(); if (!GetFromCache(valName, out val)) { try { locker.EnterWriteLock(); using (var cf = new ConfigFile()) { if (!cf.Contains(valName)) { cf.Add(valName, def); cf.Save(); val = def; } else { if (!cf.Get(valName, out val)) { val = def; } } } AddToCache(valName, val); } finally { locker.ExitWriteLock(); } } } finally { locker.ExitUpgradeableReadLock(); } return(val); }
private string GetRoutingKey(IModel model, string queueName) { _declaredQueuesLock.EnterUpgradeableReadLock(); try { if (!_declaredQueues.ContainsKey(queueName)) { _declaredQueuesLock.EnterWriteLock(); try { if (!ModelBuilder.QueueDeclare(model, queueName)) { throw new Exception($"Queue {queueName} is not declared"); } _declaredQueues.Add(queueName, null); if (_messageDelay.HasValue) { var queueNameDlx = $"{queueName}-dlx"; if (!ModelBuilder.QueueDeclare(model, queueNameDlx, new Dictionary <string, object> { { "x-dead-letter-exchange", string.Empty }, { "x-message-ttl", _messageDelay.Value }, { "x-dead-letter-routing-key", queueName } })) { throw new Exception($"Queue {queueNameDlx} is not declared"); } _declaredQueues[queueName] = queueNameDlx; } } finally { _declaredQueuesLock.ExitWriteLock(); } } return(_declaredQueues[queueName] ?? queueName); } finally { _declaredQueuesLock.ExitUpgradeableReadLock(); } }
/// <summary> /// To overcome the shortcomings of regular lock, specially in dynamic /// scenarios where we may want to write in middle of read lock or vice-versa /// for such cases we have Upgradable locks which can be modifed in middle of /// exisitng locking section. /// <code> /// _padlock.EnterUpgradeableReadLock(); /// </code> /// /// </summary> public void UpgradeLockerJob() { var x = 0; var tasks = new List <Task>(); for (int i = 0; i < 10; i++) { tasks.Add(Task.Factory.StartNew(() => { // To overcome the shortcomings of regular lock, specially in dynamic // scenarios where we may want to write in middle of read lock or vice-versa // for suc cases we have Upgradable locks which can be modifed in middle of // exisitng locking section. _padlock.EnterUpgradeableReadLock(); Console.WriteLine($"Entered Upgradable Read Lock , x = {x}"); if (i % 2 == 0) { Console.WriteLine($"Entered Upgradable Write Lock , x = {x}"); _padlock.EnterWriteLock(); x = i; _padlock.ExitWriteLock(); Console.WriteLine($"Exited Upgradable Write Lock , x = {x}"); } Thread.Sleep(2000); _padlock.ExitUpgradeableReadLock(); Console.WriteLine($"Exited Upgradable Read Lock , x = {x}"); })); try { Task.WaitAll(tasks.ToArray()); } catch (AggregateException ae) { ae.Handle(e => { Console.WriteLine(e); return(true); }); } } }
public object Get(Type pluginType, Instance instance, IBuildSession session) { object result; var key = instance.InstanceKey(pluginType); _lock.EnterUpgradeableReadLock(); try { if (_instances.Contains(instance)) { throw new StructureMapBuildException("Bi-directional dependency relationship detected!" + Environment.NewLine + "Check the StructureMap stacktrace below:"); } if (_objects.ContainsKey(key)) { result = _objects[key]; } else { _lock.EnterWriteLock(); try { _instances.Add(instance); result = buildWithSession(pluginType, instance, session); _objects.Add(key, result); } finally { _instances.Remove(instance); _lock.ExitWriteLock(); } } } finally { _lock.ExitUpgradeableReadLock(); } return(result); }
/// <summary> /// Gets a lookup table of the specified type from the cache. /// </summary> /// <param name="type">Lookup table type.</param> /// <param name="onReadyCallback">The method to call when the loading is complete if it happened asynchronously.</param> /// <returns>A lookup table of the specified type or <c>null</c> if no lookup table can be found.</returns> public virtual LookupTable GetLookupTable(string type, LookupTableReady onReadyCallback) { if (type == null) { return(null); } rwLock.EnterUpgradeableReadLock(); try { if (!cache.ContainsKey(type)) { LoadLookupTable(type, onReadyCallback); } return(cache.ContainsKey(type) ? cache[type] : null); } finally { rwLock.ExitUpgradeableReadLock(); } }
public RWScopeMgr(bool reader, ReaderWriterLockSlim rw, bool upgradable) { _reader = reader; _rw = rw; if (reader) { if (upgradable) { rw.EnterUpgradeableReadLock(); } else { rw.EnterReadLock(); } } else { rw.EnterWriteLock(); } }
public ReadLock(ReaderWriterLockSlim rwl, bool upgradeable = false, string context = null) { this.rwl = rwl; this.upgradeable = upgradeable; this.context = context; if (upgradeable) { rwl.EnterUpgradeableReadLock(); } else { rwl.EnterReadLock(); } if (context != null) { Trace.WriteLine($"Entered ReadLock '{context}'"); } }
private static byte[] GetBuffer(int size) { ThreadLocal <byte[]> threadLocal; BufferLock.EnterUpgradeableReadLock(); try { threadLocal = BufferThreadLocals[size - 1]; if (threadLocal == null) { BufferLock.EnterWriteLock(); BufferThreadLocals[size - 1] = threadLocal = new ThreadLocal <byte[]>(() => new byte[size]); } } finally { BufferLock.ExitUpgradeableReadLock(); } return(threadLocal.Value); }
private void PeriodicCheckCommands(object state) { //Console.WriteLine("{0} Total pending commands in {1}: {2}", LogTimestamp, receiver.NodeName, commandClient.Count); commandClientLock.EnterUpgradeableReadLock(); try { /* * foreach (KeyValuePair<Command,IDarPoolingCallback> pair in commandClient) * TimeSpan totalTime = DateTime.Now.Subtract(originalCommand.Timestamp); * Console.WriteLine("{0} Total time for {1}: {2}", LogTimestamp, originalCommand.GetType().Name, totalTime.TotalMilliseconds); * * Console.WriteLine("{0} {1}:Command check daemon", LogTimestamp, receiver.NodeName); */ } finally { commandClientLock.ExitUpgradeableReadLock(); } }
// ===================================== // CharacterPropertiesContract // ===================================== // ===================================== // CharacterPropertiesFillCompBook // ===================================== // ===================================== // CharacterPropertiesFriendList // ===================================== public static bool HasAsFriend(this Character character, uint friendId, ReaderWriterLockSlim rwLock) { rwLock.EnterUpgradeableReadLock(); try { foreach (var record in character.CharacterPropertiesFriendList) { if (record.FriendId == friendId) { return(true); } } return(false); } finally { rwLock.ExitUpgradeableReadLock(); } }
public LockFor(LockType type, ReaderWriterLockSlim slim) { this.lockType = type; this.lockSlim = slim; switch (lockType) { case LockType.Read: slim.EnterReadLock(); break; case LockType.Write: slim.EnterWriteLock(); break; case LockType.Upgrad: slim.EnterUpgradeableReadLock(); break; } }
private void ClientOnDisconnected(object sender, ClientDisconnectedEventArgs clientDisconnectedEventArgs) { clientLock.EnterUpgradeableReadLock(); try { var clientId = clientDisconnectedEventArgs.ClientId; if (!connectedClients.ContainsKey(clientId)) { return; } clientLock.EnterWriteLock(); try { connectedClients.Remove(clientId); } finally { clientLock.ExitWriteLock(); } OnClientDisconnected(clientId); } finally { clientLock.ExitUpgradeableReadLock(); } }
public static Set GetSet(this ICard card) { try { GetSetLock.EnterUpgradeableReadLock(); Set ret = null; if (!CardSetIndex.TryGetValue(card.SetId, out ret)) { GetSetLock.EnterWriteLock(); ret = SetManager.Get().GetById(card.SetId); CardSetIndex[card.SetId] = ret; GetSetLock.ExitWriteLock(); } return(ret); } finally { GetSetLock.ExitUpgradeableReadLock(); } }
/// <summary> /// Looks up an item in the table by a value of the item string representation /// specified by the supplied format parameter. If the table is not indexed /// by the given format, it builds such an index first. /// If multiple items have the same value for the given format, then only the /// first one will be returned and the rest of them will be stored in an attribute /// with a name composed from the <see cref="GroupAttrPrefix"/> constant and the format string. /// </summary> /// <param name="format">The format used to evaluate a string value for each item.</param> /// <param name="value">The value to look up by.</param> /// <returns>A copy of the Header item, for which evaluation of the given format /// matches the value provided. If no match is found a <c>null</c> value is returned.</returns> public Header LookupByFormat(string format, string value) { rwLock.EnterUpgradeableReadLock(); try { if (!indexedData.TryGetValue(format, out IndexedTable tbl)) { tbl = BuildIndexedTable(format); } if (tbl.TryGetValue(value, out Header res)) { return(res); } return(res); } finally { rwLock.ExitUpgradeableReadLock(); } }
private void EnterLock() { switch (m_Policy) { case AutoLockPolicy.Read: m_Locker.EnterReadLock(); break; case AutoLockPolicy.Write: m_Locker.EnterWriteLock(); break; case AutoLockPolicy.UpgradeableRead: m_Locker.EnterUpgradeableReadLock(); break; default: break; } }
private ReaderWriterLockSlim AcquireKeySpecificLock(string cacheKey) { ReaderWriterLockSlim keySpecificLock = null; _masterCollectionLock.EnterUpgradeableReadLock(); if (_constructionLocks.ContainsKey(cacheKey)) { keySpecificLock = _constructionLocks[cacheKey]; } else { try { //could have multiple threads blocking here _masterCollectionLock.EnterWriteLock(); //did another blocked thread get here first? if (_constructionLocks.ContainsKey(cacheKey)) { keySpecificLock = _constructionLocks[cacheKey]; } //nope, so create a new lock for this particular key while other threads wait else { keySpecificLock = new ReaderWriterLockSlim(); _constructionLocks.Add(cacheKey, keySpecificLock); } } catch (LockRecursionException ex) { log.Error(String.Format(CultureInfo.InvariantCulture, "Error getting lock in cache [{0}] for key [{1}]", _cacheName, cacheKey), ex); throw; } finally { //release our write lock on our lock collection _masterCollectionLock.ExitWriteLock(); } } return(keySpecificLock); }
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 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 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(); } }