ReentrancyMutex.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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.Collections.Generic;
  19. using System.Text;
  20. using System.Threading;
  21. namespace Wayne.Lib.StateEngine
  22. {
  23. /// <summary>
  24. /// A mutex class that protects not only from entering a code section from separate threads, but also
  25. /// from reentrancy by the same thread but further up on the call stack.
  26. /// </summary>
  27. class ReentrancyMutex : IDisposable
  28. {
  29. #region Fields
  30. bool owned;
  31. object mutexLock = new object();
  32. Mutex mutex = new Mutex(false);
  33. #endregion
  34. ~ReentrancyMutex()
  35. {
  36. Dispose(false);
  37. }
  38. public bool TryAquire()
  39. {
  40. lock (mutexLock)
  41. {
  42. if ((mutex != null) && mutex.WaitOne(0, false)) //First check so this thread can aquire the mutex.
  43. {
  44. if (owned) //Has this thread already the mutex, then we should fail.
  45. {
  46. mutex.ReleaseMutex();
  47. return false;
  48. }
  49. else
  50. {
  51. owned = true;
  52. return true;
  53. }
  54. }
  55. else
  56. {
  57. return false;
  58. }
  59. }
  60. }
  61. public void Release()
  62. {
  63. owned = false;
  64. lock (mutexLock)
  65. {
  66. if (mutex != null)
  67. mutex.ReleaseMutex();
  68. }
  69. }
  70. internal void Close()
  71. {
  72. ((IDisposable)this).Dispose();
  73. }
  74. #region IDisposable Members
  75. protected virtual void Dispose(bool disposing)
  76. {
  77. if (disposing)
  78. {
  79. lock (mutexLock)
  80. {
  81. if (mutex != null)
  82. {
  83. mutex.Close();
  84. mutex = null;
  85. }
  86. }
  87. }
  88. }
  89. void IDisposable.Dispose()
  90. {
  91. Dispose(true);
  92. GC.SuppressFinalize(this);
  93. }
  94. #endregion
  95. }
  96. }