///<summary>Derived class overrides <c>OnDoneReading</c> to provide specific reader unlocking semantics.</summary> ///<remarks>You do not need to override this method if the specific lock provides mutual-exclusive locking semantics.</remarks> protected override void OnLeave(Boolean write) { if (write) { // Only 1 thread is writing, so no thread safety is required here Int64 HoldTime = checked ((Int64)(Environment.TickCount - m_WriterStartHoldTime)); m_WriterMinHoldTime = Math.Min(m_WriterMinHoldTime, HoldTime); m_WriterMaxHoldTime = Math.Max(m_WriterMaxHoldTime, HoldTime); m_WritersWriting--; m_WritersDone++; InnerLock.Leave(); } else { Int32 threadId = Thread.CurrentThread.ManagedThreadId; Int64 HoldTime = checked ((Int64)(Environment.TickCount - m_ReaderStartHoldTime[threadId])); Monitor.Enter(m_ReaderStartHoldTime); m_ReaderStartHoldTime.Remove(threadId); Monitor.Exit(m_ReaderStartHoldTime); InterlockedEx.Min(ref m_ReaderMinHoldTime, HoldTime); InterlockedEx.Max(ref m_ReaderMaxHoldTime, HoldTime); Interlocked.Decrement(ref m_ReadersReading); Interlocked.Increment(ref m_ReadersDone); InnerLock.Leave(); } }
protected override void OnLeave(Boolean write) { if (write) { VerifyOneWriter("Done writing while not writing!"); VerifyNoReaders("Done writing while already reading!"); InterlockedEx.BitTestAndReset(ref m_LockState, 31); // Remove the writer } else { VerifySomeReaders("Done reading while not reading!"); VerifyNoWriters("Done reading while already writing!"); Interlocked.Decrement(ref m_LockState); // Subtract a reader } InnerLock.Leave(); }
/// <summary>Implements the ResourceLock's Leave behavior.</summary> protected override void OnLeave(Boolean exclusive) { Int32 CallingThreadId = Thread.CurrentThread.ManagedThreadId; if (exclusive) { if (m_WriterThreadIdAndRecurseCount.m_Id != CallingThreadId) { throw new InvalidOperationException("Calling thread doesn't own this lock for writing!"); } if (--m_WriterThreadIdAndRecurseCount.m_Count > 0) { return; } Interlocked.Exchange(ref m_WriterThreadIdAndRecurseCount.m_Id, 0); InnerLock.Leave(); } else { Int32 index; if (!TryFindThreadIdIndex(CallingThreadId, out index)) { throw new InvalidOperationException("Calling thread doesn't own the lock for reading!"); } // Decrement this readers recursion count if (--m_ReaderThreadIdsAndRecurseCounts[index].m_Count == 0) { // If this reader is done (recursion count == 0), remove this reader off the list Interlocked.Exchange(ref m_ReaderThreadIdsAndRecurseCounts[index].m_Id, 0); // This reader gives up the lock too InnerLock.Leave(); } } }
/// <summary>Implements the ResourceLock's Leave behavior.</summary> protected override void OnLeave(Boolean exclusive) { InnerLock.Leave(); }