Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
7 #ifndef mozilla_ReentrantMonitor_h
8 #define mozilla_ReentrantMonitor_h
10 #include "prmon.h"
12 #ifdef MOZILLA_INTERNAL_API
13 #include "GeckoProfiler.h"
14 #endif //MOZILLA_INTERNAL_API
16 #include "mozilla/BlockingResourceBase.h"
18 //
19 // Provides:
20 //
21 // - ReentrantMonitor, a Java-like monitor
22 // - ReentrantMonitorAutoEnter, an RAII class for ensuring that
23 // ReentrantMonitors are properly entered and exited
24 //
25 // Using ReentrantMonitorAutoEnter is MUCH preferred to making bare calls to
26 // ReentrantMonitor.Enter and Exit.
27 //
28 namespace mozilla {
31 /**
32 * ReentrantMonitor
33 * Java-like monitor.
34 * When possible, use ReentrantMonitorAutoEnter to hold this monitor within a
35 * scope, instead of calling Enter/Exit directly.
36 **/
37 class NS_COM_GLUE ReentrantMonitor : BlockingResourceBase
38 {
39 public:
40 /**
41 * ReentrantMonitor
42 * @param aName A name which can reference this monitor
43 */
44 ReentrantMonitor(const char* aName) :
45 BlockingResourceBase(aName, eReentrantMonitor)
46 #ifdef DEBUG
47 , mEntryCount(0)
48 #endif
49 {
50 MOZ_COUNT_CTOR(ReentrantMonitor);
51 mReentrantMonitor = PR_NewMonitor();
52 if (!mReentrantMonitor)
53 NS_RUNTIMEABORT("Can't allocate mozilla::ReentrantMonitor");
54 }
56 /**
57 * ~ReentrantMonitor
58 **/
59 ~ReentrantMonitor()
60 {
61 NS_ASSERTION(mReentrantMonitor,
62 "improperly constructed ReentrantMonitor or double free");
63 PR_DestroyMonitor(mReentrantMonitor);
64 mReentrantMonitor = 0;
65 MOZ_COUNT_DTOR(ReentrantMonitor);
66 }
68 #ifndef DEBUG
69 /**
70 * Enter
71 * @see prmon.h
72 **/
73 void Enter()
74 {
75 PR_EnterMonitor(mReentrantMonitor);
76 }
78 /**
79 * Exit
80 * @see prmon.h
81 **/
82 void Exit()
83 {
84 PR_ExitMonitor(mReentrantMonitor);
85 }
87 /**
88 * Wait
89 * @see prmon.h
90 **/
91 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
92 {
93 #ifdef MOZILLA_INTERNAL_API
94 GeckoProfilerSleepRAII profiler_sleep;
95 #endif //MOZILLA_INTERNAL_API
96 return PR_Wait(mReentrantMonitor, interval) == PR_SUCCESS ?
97 NS_OK : NS_ERROR_FAILURE;
98 }
100 #else // ifndef DEBUG
101 void Enter();
102 void Exit();
103 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
105 #endif // ifndef DEBUG
107 /**
108 * Notify
109 * @see prmon.h
110 **/
111 nsresult Notify()
112 {
113 return PR_Notify(mReentrantMonitor) == PR_SUCCESS
114 ? NS_OK : NS_ERROR_FAILURE;
115 }
117 /**
118 * NotifyAll
119 * @see prmon.h
120 **/
121 nsresult NotifyAll()
122 {
123 return PR_NotifyAll(mReentrantMonitor) == PR_SUCCESS
124 ? NS_OK : NS_ERROR_FAILURE;
125 }
127 #ifdef DEBUG
128 /**
129 * AssertCurrentThreadIn
130 * @see prmon.h
131 **/
132 void AssertCurrentThreadIn()
133 {
134 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mReentrantMonitor);
135 }
137 /**
138 * AssertNotCurrentThreadIn
139 * @see prmon.h
140 **/
141 void AssertNotCurrentThreadIn()
142 {
143 // FIXME bug 476536
144 }
146 #else
147 void AssertCurrentThreadIn()
148 {
149 }
150 void AssertNotCurrentThreadIn()
151 {
152 }
154 #endif // ifdef DEBUG
156 private:
157 ReentrantMonitor();
158 ReentrantMonitor(const ReentrantMonitor&);
159 ReentrantMonitor& operator =(const ReentrantMonitor&);
161 PRMonitor* mReentrantMonitor;
162 #ifdef DEBUG
163 int32_t mEntryCount;
164 #endif
165 };
168 /**
169 * ReentrantMonitorAutoEnter
170 * Enters the ReentrantMonitor when it enters scope, and exits it when
171 * it leaves scope.
172 *
173 * MUCH PREFERRED to bare calls to ReentrantMonitor.Enter and Exit.
174 */
175 class NS_COM_GLUE MOZ_STACK_CLASS ReentrantMonitorAutoEnter
176 {
177 public:
178 /**
179 * Constructor
180 * The constructor aquires the given lock. The destructor
181 * releases the lock.
182 *
183 * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*.
184 **/
185 ReentrantMonitorAutoEnter(mozilla::ReentrantMonitor &aReentrantMonitor) :
186 mReentrantMonitor(&aReentrantMonitor)
187 {
188 NS_ASSERTION(mReentrantMonitor, "null monitor");
189 mReentrantMonitor->Enter();
190 }
192 ~ReentrantMonitorAutoEnter(void)
193 {
194 mReentrantMonitor->Exit();
195 }
197 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
198 {
199 return mReentrantMonitor->Wait(interval);
200 }
202 nsresult Notify()
203 {
204 return mReentrantMonitor->Notify();
205 }
207 nsresult NotifyAll()
208 {
209 return mReentrantMonitor->NotifyAll();
210 }
212 private:
213 ReentrantMonitorAutoEnter();
214 ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
215 ReentrantMonitorAutoEnter& operator =(const ReentrantMonitorAutoEnter&);
216 static void* operator new(size_t) CPP_THROW_NEW;
217 static void operator delete(void*);
219 mozilla::ReentrantMonitor* mReentrantMonitor;
220 };
222 /**
223 * ReentrantMonitorAutoExit
224 * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves
225 * scope.
226 *
227 * MUCH PREFERRED to bare calls to ReentrantMonitor.Exit and Enter.
228 */
229 class MOZ_STACK_CLASS ReentrantMonitorAutoExit
230 {
231 public:
232 /**
233 * Constructor
234 * The constructor releases the given lock. The destructor
235 * acquires the lock. The lock must be held before constructing
236 * this object!
237 *
238 * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. It
239 * must be already locked.
240 **/
241 ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor) :
242 mReentrantMonitor(&aReentrantMonitor)
243 {
244 NS_ASSERTION(mReentrantMonitor, "null monitor");
245 mReentrantMonitor->AssertCurrentThreadIn();
246 mReentrantMonitor->Exit();
247 }
249 ~ReentrantMonitorAutoExit(void)
250 {
251 mReentrantMonitor->Enter();
252 }
254 private:
255 ReentrantMonitorAutoExit();
256 ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);
257 ReentrantMonitorAutoExit& operator =(const ReentrantMonitorAutoExit&);
258 static void* operator new(size_t) CPP_THROW_NEW;
259 static void operator delete(void*);
261 ReentrantMonitor* mReentrantMonitor;
262 };
264 } // namespace mozilla
267 #endif // ifndef mozilla_ReentrantMonitor_h