|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: sw=4 ts=4 et : |
|
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 "prcvar.h" |
|
11 |
|
12 #include "mozilla/BlockingResourceBase.h" |
|
13 #include "mozilla/Mutex.h" |
|
14 |
|
15 #ifdef MOZILLA_INTERNAL_API |
|
16 #include "GeckoProfiler.h" |
|
17 #endif //MOZILLA_INTERNAL_API |
|
18 |
|
19 namespace mozilla { |
|
20 |
|
21 |
|
22 /** |
|
23 * CondVar |
|
24 * Vanilla condition variable. Please don't use this unless you have a |
|
25 * compelling reason --- Monitor provides a simpler API. |
|
26 */ |
|
27 class NS_COM_GLUE CondVar : BlockingResourceBase |
|
28 { |
|
29 public: |
|
30 /** |
|
31 * CondVar |
|
32 * |
|
33 * The CALLER owns |lock|. |
|
34 * |
|
35 * @param aLock A Mutex to associate with this condition variable. |
|
36 * @param aName A name which can reference this monitor |
|
37 * @returns If failure, nullptr. |
|
38 * If success, a valid Monitor* which must be destroyed |
|
39 * by Monitor::DestroyMonitor() |
|
40 **/ |
|
41 CondVar(Mutex& aLock, const char* aName) : |
|
42 BlockingResourceBase(aName, eCondVar), |
|
43 mLock(&aLock) |
|
44 { |
|
45 MOZ_COUNT_CTOR(CondVar); |
|
46 // |lock| must necessarily already be known to the deadlock detector |
|
47 mCvar = PR_NewCondVar(mLock->mLock); |
|
48 if (!mCvar) |
|
49 NS_RUNTIMEABORT("Can't allocate mozilla::CondVar"); |
|
50 } |
|
51 |
|
52 /** |
|
53 * ~CondVar |
|
54 * Clean up after this CondVar, but NOT its associated Mutex. |
|
55 **/ |
|
56 ~CondVar() |
|
57 { |
|
58 NS_ASSERTION(mCvar && mLock, |
|
59 "improperly constructed CondVar or double free"); |
|
60 PR_DestroyCondVar(mCvar); |
|
61 mCvar = 0; |
|
62 mLock = 0; |
|
63 MOZ_COUNT_DTOR(CondVar); |
|
64 } |
|
65 |
|
66 #ifndef DEBUG |
|
67 /** |
|
68 * Wait |
|
69 * @see prcvar.h |
|
70 **/ |
|
71 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT) |
|
72 { |
|
73 |
|
74 #ifdef MOZILLA_INTERNAL_API |
|
75 GeckoProfilerSleepRAII profiler_sleep; |
|
76 #endif //MOZILLA_INTERNAL_API |
|
77 // NSPR checks for lock ownership |
|
78 return PR_WaitCondVar(mCvar, interval) == PR_SUCCESS |
|
79 ? NS_OK : NS_ERROR_FAILURE; |
|
80 } |
|
81 #else |
|
82 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT); |
|
83 #endif // ifndef DEBUG |
|
84 |
|
85 /** |
|
86 * Notify |
|
87 * @see prcvar.h |
|
88 **/ |
|
89 nsresult Notify() |
|
90 { |
|
91 // NSPR checks for lock ownership |
|
92 return PR_NotifyCondVar(mCvar) == PR_SUCCESS |
|
93 ? NS_OK : NS_ERROR_FAILURE; |
|
94 } |
|
95 |
|
96 /** |
|
97 * NotifyAll |
|
98 * @see prcvar.h |
|
99 **/ |
|
100 nsresult NotifyAll() |
|
101 { |
|
102 // NSPR checks for lock ownership |
|
103 return PR_NotifyAllCondVar(mCvar) == PR_SUCCESS |
|
104 ? NS_OK : NS_ERROR_FAILURE; |
|
105 } |
|
106 |
|
107 #ifdef DEBUG |
|
108 /** |
|
109 * AssertCurrentThreadOwnsMutex |
|
110 * @see Mutex::AssertCurrentThreadOwns |
|
111 **/ |
|
112 void AssertCurrentThreadOwnsMutex() |
|
113 { |
|
114 mLock->AssertCurrentThreadOwns(); |
|
115 } |
|
116 |
|
117 /** |
|
118 * AssertNotCurrentThreadOwnsMutex |
|
119 * @see Mutex::AssertNotCurrentThreadOwns |
|
120 **/ |
|
121 void AssertNotCurrentThreadOwnsMutex() |
|
122 { |
|
123 mLock->AssertNotCurrentThreadOwns(); |
|
124 } |
|
125 |
|
126 #else |
|
127 void AssertCurrentThreadOwnsMutex() |
|
128 { |
|
129 } |
|
130 void AssertNotCurrentThreadOwnsMutex() |
|
131 { |
|
132 } |
|
133 |
|
134 #endif // ifdef DEBUG |
|
135 |
|
136 private: |
|
137 CondVar(); |
|
138 CondVar(CondVar&); |
|
139 CondVar& operator=(CondVar&); |
|
140 |
|
141 Mutex* mLock; |
|
142 PRCondVar* mCvar; |
|
143 }; |
|
144 |
|
145 |
|
146 } // namespace mozilla |
|
147 |
|
148 |
|
149 #endif // ifndef mozilla_CondVar_h |