/// <summary> /// Prevents write operations from deadlocking by throwing a <see cref="TimeoutException"/> if <see cref="WriteWaitEvent"/> is not available /// within <see cref="ReadWriteTimeout"/>. /// </summary> private void WriteWait() { if (!WriteWaitEvent.WaitOne(ReadWriteTimeout)) { throw new TimeoutException(RS.WriteOperationTimedOut); } }
/// <summary> /// Prevents write operations from deadlocking by throwing a TimeoutException if the WriteWaitEvent is not available within <see cref="ReadWriteTimeout"/> milliseconds /// </summary> private void WriteWait() { if (!WriteWaitEvent.WaitOne(ReadWriteTimeout)) { throw new TimeoutException("The write operation timed out waiting for the write lock WaitEvent. Check your usage of AcquireWriteLock/ReleaseWriteLock and AcquireReadLock/ReleaseReadLock."); } }
/// <summary> /// Blocks the current thread until it is able to acquire a write lock. If successful all subsequent reads will be blocked until after a call to <see cref="ReleaseWriteLock"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or System.Threading.Timeout.Infinite (-1) to wait indefinitely.</param> /// <returns>true if the write lock was able to be acquired, otherwise false.</returns> /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1, which represents an infinite time-out.</exception> /// <remarks>If <paramref name="millisecondsTimeout"/> is <see cref="System.Threading.Timeout.Infinite" /> (-1), then attempting to acquire a write lock after acquiring a read lock on the same thread will result in a deadlock.</remarks> public bool AcquireWriteLock(int millisecondsTimeout = System.Threading.Timeout.Infinite) { if (!WriteWaitEvent.WaitOne(millisecondsTimeout)) { return(false); } ReadWaitEvent.Reset(); return(true); }
/// <summary> /// Blocks the current thread until it is able to acquire a read lock. If successful, all subsequent writes will be blocked until after a /// call to <see cref="ReleaseReadLock"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="Timeout.Infinite" /> to wait indefinitely.</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1, which represents an infinite time-out.</exception> /// <returns>`true` if the read lock was acquired successfully. Otherwise, `false`.</returns> /// <remarks> /// If <paramref name="millisecondsTimeout"/> is <see cref="Timeout.Infinite" />, then attempting to acquire a read lock after acquiring a write lock /// on the same thread will result in a deadlock. /// </remarks> public bool AcquireReadLock(int millisecondsTimeout = Timeout.Infinite) { if (!ReadWaitEvent.WaitOne(millisecondsTimeout)) { return(false); } WriteWaitEvent.Reset(); return(true); }
/// <summary> /// Releases the current read lock, allowing all blocked writes to continue. /// </summary> public void ReleaseReadLock() { WriteWaitEvent.Set(); }
/// <summary> /// Prepares an IntPtr to the buffer position and calls <paramref name="writeFunc"/> to perform the writing. /// </summary> /// <param name="writeFunc">A function used to write to the buffer. The IntPtr parameter is a pointer to the buffer offset by <paramref name="bufferPosition"/>.</param> /// <param name="bufferPosition">The offset within the buffer region to start writing from.</param> protected override void Write(Action <IntPtr> writeFunc, long bufferPosition = 0) { WriteWaitEvent.WaitOne(); base.Write(writeFunc, bufferPosition); }
/// <summary> /// Writes <paramref name="length"/> bytes from the <paramref name="ptr"/> into the shared memory buffer. /// </summary> /// <param name="ptr">A managed pointer to the memory location to be copied into the buffer</param> /// <param name="length">The number of bytes to be copied</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> protected override void Write(IntPtr ptr, int length, long bufferPosition = 0) { WriteWaitEvent.WaitOne(); base.Write(ptr, length, bufferPosition); }
/// <summary> /// Writes an array of <typeparamref name="T"/> into the buffer /// </summary> /// <typeparam name="T">A structure type</typeparam> /// <param name="buffer">An array of <typeparamref name="T"/> to be written. The length of this array controls the number of elements to be written.</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> protected override void Write <T>(T[] buffer, long bufferPosition = 0) { WriteWaitEvent.WaitOne(); base.Write <T>(buffer, bufferPosition); }
/// <summary> /// Writes an instance of <typeparamref name="T"/> into the buffer /// </summary> /// <typeparam name="T">A structure type</typeparam> /// <param name="data">A reference to an instance of <typeparamref name="T"/> to be written</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> protected override void Write <T>(ref T data, long bufferPosition = 0) { WriteWaitEvent.WaitOne(); base.Write <T>(ref data, bufferPosition); }