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);
}
}
}