#region --------------- Copyright Dresser Wayne Pignone ------------- /* * $Log: /Wrk/WayneLibraries/Wrk/StateEngine/ReentrancyMutex.cs $ * * 4 07-12-06 11:27 Mattias.larsson * * 3 07-10-28 14:47 roger.månsson * Added a lock on the mutex object, so we can dispose without exceptions. * * 2 07-10-22 16:21 roger.månsson * Corrected handling of reentrancy. Must set the owned flag! * * 1 07-10-22 11:30 roger.månsson * Created */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace Wayne.Lib.StateEngine { /// /// A mutex class that protects not only from entering a code section from separate threads, but also /// from reentrancy by the same thread but further up on the call stack. /// class ReentrancyMutex : IDisposable { #region Fields bool owned; object mutexLock = new object(); Mutex mutex = new Mutex(false); #endregion ~ReentrancyMutex() { Dispose(false); } public bool TryAquire() { lock (mutexLock) { if ((mutex != null) && mutex.WaitOne(0, false)) //First check so this thread can aquire the mutex. { if (owned) //Has this thread already the mutex, then we should fail. { mutex.ReleaseMutex(); return false; } else { owned = true; return true; } } else { return false; } } } public void Release() { owned = false; lock (mutexLock) { if (mutex != null) mutex.ReleaseMutex(); } } internal void Close() { ((IDisposable)this).Dispose(); } #region IDisposable Members protected virtual void Dispose(bool disposing) { if (disposing) { lock (mutexLock) { if (mutex != null) { mutex.Close(); mutex = null; } } } } void IDisposable.Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } }