ReentrancyMutex.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #region --------------- Copyright Dresser Wayne Pignone -------------
  2. /*
  3. * $Log: /Wrk/WayneLibraries/Wrk/StateEngine/ReentrancyMutex.cs $
  4. *
  5. * 4 07-12-06 11:27 Mattias.larsson
  6. *
  7. * 3 07-10-28 14:47 roger.månsson
  8. * Added a lock on the mutex object, so we can dispose without exceptions.
  9. *
  10. * 2 07-10-22 16:21 roger.månsson
  11. * Corrected handling of reentrancy. Must set the owned flag!
  12. *
  13. * 1 07-10-22 11:30 roger.månsson
  14. * Created
  15. */
  16. #endregion
  17. using System;
  18. using System.Threading;
  19. namespace Wayne.Lib.StateEngine
  20. {
  21. /// <summary>
  22. /// A mutex class that protects not only from entering a code section from separate threads, but also
  23. /// from reentrancy by the same thread but further up on the call stack.
  24. /// </summary>
  25. class ReentrancyMutex : IDisposable
  26. {
  27. #region Fields
  28. bool owned;
  29. object mutexLock = new object();
  30. Mutex mutex = new Mutex(false);
  31. #endregion
  32. ~ReentrancyMutex()
  33. {
  34. Dispose(false);
  35. }
  36. public bool TryAquire()
  37. {
  38. lock (mutexLock)
  39. {
  40. if ((mutex != null) && mutex.WaitOne(0, false)) //First check so this thread can aquire the mutex.
  41. {
  42. if (owned) //Has this thread already the mutex, then we should fail.
  43. {
  44. mutex.ReleaseMutex();
  45. return false;
  46. }
  47. else
  48. {
  49. owned = true;
  50. return true;
  51. }
  52. }
  53. else
  54. {
  55. return false;
  56. }
  57. }
  58. }
  59. public void Release()
  60. {
  61. owned = false;
  62. lock (mutexLock)
  63. {
  64. if (mutex != null)
  65. mutex.ReleaseMutex();
  66. }
  67. }
  68. internal void Close()
  69. {
  70. ((IDisposable)this).Dispose();
  71. }
  72. #region IDisposable Members
  73. protected virtual void Dispose(bool disposing)
  74. {
  75. if (disposing)
  76. {
  77. lock (mutexLock)
  78. {
  79. if (mutex != null)
  80. {
  81. mutex.Close();
  82. mutex = null;
  83. }
  84. }
  85. }
  86. }
  87. void IDisposable.Dispose()
  88. {
  89. Dispose(true);
  90. GC.SuppressFinalize(this);
  91. }
  92. #endregion
  93. }
  94. }