Adding a timeout of 5mins to SafeCriticalSection in Debug builds for diagnosing deadlocks

This commit is contained in:
Chris Cameron
2017-09-05 10:29:49 -04:00
parent 0284026053
commit face402a19

View File

@@ -1,4 +1,5 @@
#if SIMPLSHARP using System;
#if SIMPLSHARP
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace ICD.Common.Utils namespace ICD.Common.Utils
@@ -10,14 +11,24 @@ namespace ICD.Common.Utils
/// </summary> /// </summary>
public sealed partial class SafeCriticalSection public sealed partial class SafeCriticalSection
{ {
#if DEBUG
private const int TIMEOUT = 5 * 60 * 1000;
private readonly CMutex m_CriticalSection;
#else
private readonly CCriticalSection m_CriticalSection; private readonly CCriticalSection m_CriticalSection;
#endif
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
public SafeCriticalSection() public SafeCriticalSection()
{ {
#if DEBUG
m_CriticalSection = new CMutex();
#else
m_CriticalSection = new CCriticalSection(); m_CriticalSection = new CCriticalSection();
#endif
} }
#region Methods #region Methods
@@ -27,10 +38,21 @@ namespace ICD.Common.Utils
/// </summary> /// </summary>
public void Enter() public void Enter()
{ {
if (m_CriticalSection == null || m_CriticalSection.Disposed) if (m_CriticalSection == null)
return; return;
m_CriticalSection.Enter(); try
{
#if DEBUG
if (!m_CriticalSection.WaitForMutex(TIMEOUT))
throw new InvalidProgramException("Deadlock detected in program");
#else
m_CriticalSection.Enter();
#endif
}
catch (ObjectDisposedException)
{
}
} }
/// <summary> /// <summary>
@@ -38,10 +60,20 @@ namespace ICD.Common.Utils
/// </summary> /// </summary>
public void Leave() public void Leave()
{ {
if (m_CriticalSection == null || m_CriticalSection.Disposed) if (m_CriticalSection == null)
return; return;
m_CriticalSection.Leave(); try
{
#if DEBUG
m_CriticalSection.ReleaseMutex();
#else
m_CriticalSection.Leave();
#endif
}
catch (ObjectDisposedException)
{
}
} }
/// <summary> /// <summary>
@@ -52,10 +84,21 @@ namespace ICD.Common.Utils
/// </returns> /// </returns>
public bool TryEnter() public bool TryEnter()
{ {
if (m_CriticalSection == null || m_CriticalSection.Disposed) if (m_CriticalSection == null)
return false; return false;
return m_CriticalSection.TryEnter(); try
{
#if DEBUG
return m_CriticalSection.WaitForMutex(0);
#else
return m_CriticalSection.TryEnter();
#endif
}
catch (ObjectDisposedException)
{
return false;
}
} }
#endregion #endregion