Monitor.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_Monitor_h
  6. #define mozilla_Monitor_h
  7. #include "mozilla/CondVar.h"
  8. #include "mozilla/Mutex.h"
  9. namespace mozilla {
  10. /**
  11. * Monitor provides a *non*-reentrant monitor: *not* a Java-style
  12. * monitor. If your code needs support for reentrancy, use
  13. * ReentrantMonitor instead. (Rarely should reentrancy be needed.)
  14. *
  15. * Instead of directly calling Monitor methods, it's safer and simpler
  16. * to instead use the RAII wrappers MonitorAutoLock and
  17. * MonitorAutoUnlock.
  18. */
  19. class Monitor
  20. {
  21. public:
  22. explicit Monitor(const char* aName)
  23. : mMutex(aName)
  24. , mCondVar(mMutex, "[Monitor.mCondVar]")
  25. {
  26. }
  27. ~Monitor() {}
  28. void Lock() { mMutex.Lock(); }
  29. void Unlock() { mMutex.Unlock(); }
  30. nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
  31. {
  32. return mCondVar.Wait(aInterval);
  33. }
  34. nsresult Notify() { return mCondVar.Notify(); }
  35. nsresult NotifyAll() { return mCondVar.NotifyAll(); }
  36. void AssertCurrentThreadOwns() const
  37. {
  38. mMutex.AssertCurrentThreadOwns();
  39. }
  40. void AssertNotCurrentThreadOwns() const
  41. {
  42. mMutex.AssertNotCurrentThreadOwns();
  43. }
  44. private:
  45. Monitor();
  46. Monitor(const Monitor&);
  47. Monitor& operator=(const Monitor&);
  48. Mutex mMutex;
  49. CondVar mCondVar;
  50. };
  51. /**
  52. * Lock the monitor for the lexical scope instances of this class are
  53. * bound to (except for MonitorAutoUnlock in nested scopes).
  54. *
  55. * The monitor must be unlocked when instances of this class are
  56. * created.
  57. */
  58. class MOZ_STACK_CLASS MonitorAutoLock
  59. {
  60. public:
  61. explicit MonitorAutoLock(Monitor& aMonitor)
  62. : mMonitor(&aMonitor)
  63. {
  64. mMonitor->Lock();
  65. }
  66. ~MonitorAutoLock()
  67. {
  68. mMonitor->Unlock();
  69. }
  70. nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
  71. {
  72. return mMonitor->Wait(aInterval);
  73. }
  74. nsresult Notify() { return mMonitor->Notify(); }
  75. nsresult NotifyAll() { return mMonitor->NotifyAll(); }
  76. private:
  77. MonitorAutoLock();
  78. MonitorAutoLock(const MonitorAutoLock&);
  79. MonitorAutoLock& operator=(const MonitorAutoLock&);
  80. static void* operator new(size_t) CPP_THROW_NEW;
  81. Monitor* mMonitor;
  82. };
  83. /**
  84. * Unlock the monitor for the lexical scope instances of this class
  85. * are bound to (except for MonitorAutoLock in nested scopes).
  86. *
  87. * The monitor must be locked by the current thread when instances of
  88. * this class are created.
  89. */
  90. class MOZ_STACK_CLASS MonitorAutoUnlock
  91. {
  92. public:
  93. explicit MonitorAutoUnlock(Monitor& aMonitor)
  94. : mMonitor(&aMonitor)
  95. {
  96. mMonitor->Unlock();
  97. }
  98. ~MonitorAutoUnlock()
  99. {
  100. mMonitor->Lock();
  101. }
  102. private:
  103. MonitorAutoUnlock();
  104. MonitorAutoUnlock(const MonitorAutoUnlock&);
  105. MonitorAutoUnlock& operator=(const MonitorAutoUnlock&);
  106. static void* operator new(size_t) CPP_THROW_NEW;
  107. Monitor* mMonitor;
  108. };
  109. } // namespace mozilla
  110. #endif // mozilla_Monitor_h