/// <summary> /// Removes a context from the context pool. /// </summary> /// <param name="context">The context to remove.</param> /// <returns>False if the context does not exist, true otherwise.</returns> public static bool RemoveContext(string context) { bool retval = true; readWriteLock.AcquireReaderLock(MAX_LOCK_WAIT); try { if (caches.ContainsKey(context)) { caches[context].Clear(); LockCookie lc = readWriteLock.UpgradeToWriterLock(MAX_LOCK_WAIT); try { caches.Remove(context); } finally { readWriteLock.DowngradeFromWriterLock(ref lc); } } else { retval = false; } } finally { readWriteLock.ReleaseReaderLock(); } return(retval); }
public static void DoActionWithWriterLock(Action funcToRun) { bool hadReaderLock = false; bool hadWriterLock = false; LockCookie cookie; if (!_lock.IsWriterLockHeld) { if (_lock.IsReaderLockHeld) { hadReaderLock = true; cookie = _lock.UpgradeToWriterLock(_writerLockTimeoutMs); } if (!_lock.IsWriterLockHeld) { _lock.AcquireWriterLock(_writerLockTimeoutMs); } } else { hadWriterLock = true; } if (!_lock.IsWriterLockHeld) { throw new ApplicationException("Unable to acquire WRITER lock on CommandQueue after waiting " + _writerLockTimeoutMs + " milliseconds."); } //do the thing funcToRun(); if (hadWriterLock) { //keep it } else if (hadReaderLock && _lock.IsWriterLockHeld) { //Reset the _lock.DowngradeFromWriterLock(ref cookie); } else { //release it all _lock.ReleaseWriterLock(); } }
public void DowngradeTest () { LockCookie lc1, lc2, lc3, lc4; rwlock = new ReaderWriterLock (); rwlock.AcquireReaderLock (Timeout.Infinite); lc1 = rwlock.UpgradeToWriterLock (Timeout.Infinite); rwlock.AcquireReaderLock (Timeout.Infinite); lc2 = rwlock.UpgradeToWriterLock (Timeout.Infinite); rwlock.AcquireReaderLock (Timeout.Infinite); lc3 = rwlock.UpgradeToWriterLock (Timeout.Infinite); rwlock.AcquireReaderLock (Timeout.Infinite); lc4 = rwlock.UpgradeToWriterLock (Timeout.Infinite); rwlock.DowngradeFromWriterLock (ref lc2); Assert.IsFalse (rwlock.IsReaderLockHeld, "A1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "A2"); rwlock.ReleaseReaderLock (); Assert.IsFalse (rwlock.IsReaderLockHeld, "B1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "B2"); rwlock.DowngradeFromWriterLock (ref lc4); Assert.IsFalse (rwlock.IsReaderLockHeld, "C1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "C2"); rwlock.ReleaseReaderLock (); Assert.IsFalse (rwlock.IsReaderLockHeld, "D1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "D2"); rwlock.DowngradeFromWriterLock (ref lc3); Assert.IsFalse (rwlock.IsReaderLockHeld, "E1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "E2"); rwlock.ReleaseReaderLock (); Assert.IsFalse (rwlock.IsReaderLockHeld, "F1"); Assert.IsTrue (rwlock.IsWriterLockHeld, "F2"); rwlock.DowngradeFromWriterLock (ref lc1); Assert.IsTrue (rwlock.IsReaderLockHeld, "G1"); Assert.IsFalse (rwlock.IsWriterLockHeld, "G2"); rwlock.ReleaseReaderLock (); Assert.IsFalse (rwlock.IsReaderLockHeld, "H1"); Assert.IsFalse (rwlock.IsWriterLockHeld, "H2"); }
public void TestUpgradeDowngradeLock () { rwlock = new ReaderWriterLock (); rwlock.AcquireReaderLock (200); rwlock.AcquireReaderLock (200); LockCookie co = rwlock.UpgradeToWriterLock (200); Assert.IsTrue (!rwlock.IsReaderLockHeld); Assert.IsTrue (rwlock.IsWriterLockHeld); RunThread (new ThreadStart (AcquireLock_writerFails)); rwlock.DowngradeFromWriterLock (ref co); Assert.IsTrue (rwlock.IsReaderLockHeld); Assert.IsTrue (!rwlock.IsWriterLockHeld); RunThread (new ThreadStart (AcquireLock_readerWorks)); rwlock.ReleaseReaderLock (); Assert.IsTrue (rwlock.IsReaderLockHeld); rwlock.ReleaseReaderLock (); Assert.IsTrue (!rwlock.IsReaderLockHeld); }
public static IDisposable UpgradeToWriterLock(ReaderWriterLock rwl) { var lockCookie = rwl.UpgradeToWriterLock(Timeout.Infinite); return new Disposer(() => rwl.DowngradeFromWriterLock(ref lockCookie)); }
/// <summary> /// Registers a single local event handler. /// Local event handlers will only be called if the /// "sender" parameter in the Notify method equals /// the object for which a local event handler was /// registered. /// </summary> /// <remarks> /// Certain events will never have a local event handler. /// This happens if the Notify method is called without /// a sender parameter for example! /// </remarks> /// <param name="obj">The object that needs to be the sender of events</param> /// <param name="e">The event type to register for</param> /// <param name="del">The event handler to register for this event type</param> /// <param name="unique">Flag wether event shall be added unique or not</param> /// <exception cref="ArgumentNullException">If one of the parameters is null</exception> private static void AddHandler(object obj, RoadEvent e, RoadEventHandler del, bool unique) { //Test the parameters if (obj == null) { throw new ArgumentNullException("obj", "No object given!"); } if (e == null) { throw new ArgumentNullException("e", "No event type given!"); } if (del == null) { throw new ArgumentNullException("del", "No event handler given!"); } if (!e.IsValidFor(obj)) { throw new ArgumentException("Object is not valid for this event type", "obj"); } try { m_lock.AcquireReaderLock(TIMEOUT); try { RoadEventHandlerCollection col = (RoadEventHandlerCollection)m_GameObjectEventCollections[obj]; if (col == null) { col = new RoadEventHandlerCollection(); LockCookie lc = m_lock.UpgradeToWriterLock(TIMEOUT); try { m_GameObjectEventCollections[obj] = col; } finally { m_lock.DowngradeFromWriterLock(ref lc); } } if (unique) { col.AddHandlerUnique(e, del); } else { col.AddHandler(e, del); } } finally { m_lock.ReleaseReaderLock(); } } catch (ApplicationException ex) { if (log.IsErrorEnabled) { log.Error("Failed to add local event handler!", ex); } } }
/// <summary> /// Executes a job on demand, rather than waiting for its regularly scheduled time. /// </summary> /// <param name="job">The job to be executed.</param> public static void ExecuteJob(JobBase job) { ReaderWriterLock rwLock = new ReaderWriterLock(); try { rwLock.AcquireReaderLock(Timeout.Infinite); if (job.Executing == false) { LockCookie lockCookie = rwLock.UpgradeToWriterLock(Timeout.Infinite); try { if (job.Executing == false) { job.Executing = true; QueueJob(job); } } finally { rwLock.DowngradeFromWriterLock(ref lockCookie); } } } finally { rwLock.ReleaseReaderLock(); } }