diff --git a/ICD.Common.Utils/Threading/SafeMutex.cs b/ICD.Common.Utils/Threading/SafeMutex.cs
index 66c2798..97bdb53 100644
--- a/ICD.Common.Utils/Threading/SafeMutex.cs
+++ b/ICD.Common.Utils/Threading/SafeMutex.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
#if SIMPLSHARP
using Crestron.SimplSharp;
#else
@@ -12,8 +12,10 @@ namespace ICD.Common.Utils
/// done with it. This class is an attempt to gracefully handle the ObjectDisposedExceptions
/// we see on program termination, ocassionally causing the program to restart instead of stop.
///
- public sealed class SafeMutex
+ public sealed class SafeMutex : IDisposable
{
+ private bool _disposedValue;
+
#if SIMPLSHARP
private readonly CMutex m_Mutex;
#else
@@ -21,8 +23,8 @@ namespace ICD.Common.Utils
#endif
///
- /// Constructor.
- ///
+ /// Initializes a new instance of the class.
+ ///
public SafeMutex()
{
#if SIMPLSHARP
@@ -31,7 +33,20 @@ namespace ICD.Common.Utils
m_Mutex = new Mutex();
#endif
}
-
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public SafeMutex(bool initiallyOwned)
+ {
+#if SIMPLSHARP
+ m_Mutex = new CMutex(initiallyOwned);
+#else
+ m_Mutex = new Mutex(initiallyOwned);
+#endif
+ }
+
#region Methods
///
@@ -46,7 +61,7 @@ namespace ICD.Common.Utils
#if SIMPLSHARP
return m_Mutex.WaitForMutex(timeout);
#else
- return m_Mutex.WaitOne(timeout);
+ return m_Mutex.WaitOne(timeout);
#endif
}
catch (ObjectDisposedException)
@@ -71,5 +86,50 @@ namespace ICD.Common.Utils
}
#endregion
- }
+
+ #region IDisposable
+
+ private void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // dispose managed state (managed objects)
+ try
+ {
+ // disposing of a mutex automatically releases it. Match that behavior
+ m_mutex.ReleaseMutex();
+ m_Mutex.Dispose();
+ }
+ catch (ObjectDisposedException)
+ {
+ // Releasing a disposed mutex in this case is valid behaviour
+ }
+ }
+
+ // free unmanaged resources (unmanaged objects) and override finalizer
+ // set large fields to null
+ _disposedValue = true;
+ }
+ }
+
+
+ // override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
+ // ~CaMutex()
+ // {
+ // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ // Dispose(disposing: false);
+ // }
+
+ ///
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+ }
}