1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_CondVar_h 8 #define mozilla_CondVar_h 9 10 #include "mozilla/BlockingResourceBase.h" 11 #include "mozilla/PlatformConditionVariable.h" 12 #include "mozilla/Mutex.h" 13 #include "mozilla/TimeStamp.h" 14 15 #if defined(MOZILLA_INTERNAL_API) && !defined(DEBUG) 16 # include "GeckoProfiler.h" 17 #endif // defined( MOZILLA_INTERNAL_API) && !defined(DEBUG) 18 19 namespace mozilla { 20 21 /** 22 * Similarly to OffTheBooksMutex, OffTheBooksCondvar is identical to CondVar, 23 * except that OffTheBooksCondVar doesn't include leak checking. Sometimes 24 * you want to intentionally "leak" a CondVar until shutdown; in these cases, 25 * OffTheBooksCondVar is for you. 26 */ 27 class OffTheBooksCondVar : BlockingResourceBase { 28 public: 29 /** 30 * OffTheBooksCondVar 31 * 32 * The CALLER owns |aLock|. 33 * 34 * @param aLock A Mutex to associate with this condition variable. 35 * @param aName A name which can reference this monitor 36 * @returns If failure, nullptr. 37 * If success, a valid Monitor* which must be destroyed 38 * by Monitor::DestroyMonitor() 39 **/ OffTheBooksCondVar(OffTheBooksMutex & aLock,const char * aName)40 OffTheBooksCondVar(OffTheBooksMutex& aLock, const char* aName) 41 : BlockingResourceBase(aName, eCondVar), mLock(&aLock) {} 42 43 /** 44 * ~OffTheBooksCondVar 45 * Clean up after this OffTheBooksCondVar, but NOT its associated Mutex. 46 **/ 47 ~OffTheBooksCondVar() = default; 48 49 /** 50 * Wait 51 * @see prcvar.h 52 **/ 53 #ifndef DEBUG Wait()54 void Wait() { 55 # ifdef MOZILLA_INTERNAL_API 56 AUTO_PROFILER_THREAD_SLEEP; 57 # endif // MOZILLA_INTERNAL_API 58 mImpl.wait(*mLock); 59 } 60 Wait(TimeDuration aDuration)61 CVStatus Wait(TimeDuration aDuration) { 62 # ifdef MOZILLA_INTERNAL_API 63 AUTO_PROFILER_THREAD_SLEEP; 64 # endif // MOZILLA_INTERNAL_API 65 return mImpl.wait_for(*mLock, aDuration); 66 } 67 #else 68 // NOTE: debug impl is in BlockingResourceBase.cpp 69 void Wait(); 70 CVStatus Wait(TimeDuration aDuration); 71 #endif 72 73 /** 74 * Notify 75 * @see prcvar.h 76 **/ Notify()77 void Notify() { mImpl.notify_one(); } 78 79 /** 80 * NotifyAll 81 * @see prcvar.h 82 **/ NotifyAll()83 void NotifyAll() { mImpl.notify_all(); } 84 85 #ifdef DEBUG 86 /** 87 * AssertCurrentThreadOwnsMutex 88 * @see Mutex::AssertCurrentThreadOwns 89 **/ AssertCurrentThreadOwnsMutex()90 void AssertCurrentThreadOwnsMutex() { mLock->AssertCurrentThreadOwns(); } 91 92 /** 93 * AssertNotCurrentThreadOwnsMutex 94 * @see Mutex::AssertNotCurrentThreadOwns 95 **/ AssertNotCurrentThreadOwnsMutex()96 void AssertNotCurrentThreadOwnsMutex() { 97 mLock->AssertNotCurrentThreadOwns(); 98 } 99 100 #else AssertCurrentThreadOwnsMutex()101 void AssertCurrentThreadOwnsMutex() {} AssertNotCurrentThreadOwnsMutex()102 void AssertNotCurrentThreadOwnsMutex() {} 103 104 #endif // ifdef DEBUG 105 106 private: 107 OffTheBooksCondVar(); 108 OffTheBooksCondVar(const OffTheBooksCondVar&) = delete; 109 OffTheBooksCondVar& operator=(const OffTheBooksCondVar&) = delete; 110 111 OffTheBooksMutex* mLock; 112 detail::ConditionVariableImpl mImpl; 113 }; 114 115 /** 116 * CondVar 117 * Vanilla condition variable. Please don't use this unless you have a 118 * compelling reason --- Monitor provides a simpler API. 119 */ 120 class CondVar : public OffTheBooksCondVar { 121 public: CondVar(OffTheBooksMutex & aLock,const char * aName)122 CondVar(OffTheBooksMutex& aLock, const char* aName) 123 : OffTheBooksCondVar(aLock, aName) { 124 MOZ_COUNT_CTOR(CondVar); 125 } 126 127 MOZ_COUNTED_DTOR(CondVar) 128 129 private: 130 CondVar(); 131 CondVar(const CondVar&); 132 CondVar& operator=(const CondVar&); 133 }; 134 135 } // namespace mozilla 136 137 #endif // ifndef mozilla_CondVar_h 138