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