using System; using System.Threading; namespace ProcessHacker.Common.Threading { /// /// Provides methods for synchronizing access to a shared resource. /// /// Just a wrapper around Monitor (minus the event methods /// like Pulse and Wait). public sealed class FastMutex { /// /// Represents a context for mutex acquisition. /// public struct FastMutexContext : IDisposable { private bool _disposed; private FastMutex _fastMutex; internal FastMutexContext(FastMutex fastMutex) { _fastMutex = fastMutex; _disposed = false; } /// /// Releases the mutex. /// public void Dispose() { if (!_disposed) { _fastMutex.Release(); _disposed = true; } } } private object _lock = new object(); /// /// Acquires the mutex and prevents others from acquiring it. /// If the mutex is already acquired, the function will block /// until it can acquire the mutex. /// public void Acquire() { Monitor.Enter(_lock); } /// /// Acquires the mutex and returns a context object which /// must be disposed to release the mutex. /// /// The context object. public FastMutexContext AcquireContext() { this.Acquire(); return new FastMutexContext(this); } /// /// Releases the mutex and allows others to acquire the mutex. /// public void Release() { Monitor.Exit(_lock); } /// /// Attempts to acquire the mutex and returns immediately /// regardless of whether the mutex was acquired. /// /// Whether or not the mutex was acquired. public bool TryAcquire() { return Monitor.TryEnter(_lock); } /// /// Attempts to acquire the mutex and returns after a /// timeout period if the mutex could not be acquired. /// /// The timeout, in milliseconds. /// Whether or not the mutex was acquired. public bool TryAcquire(int millisecondsTimeout) { return Monitor.TryEnter(_lock, millisecondsTimeout); } } }