xpcom/glue/ReentrantMonitor.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: sw=4 ts=4 et :
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef mozilla_ReentrantMonitor_h
michael@0 8 #define mozilla_ReentrantMonitor_h
michael@0 9
michael@0 10 #include "prmon.h"
michael@0 11
michael@0 12 #ifdef MOZILLA_INTERNAL_API
michael@0 13 #include "GeckoProfiler.h"
michael@0 14 #endif //MOZILLA_INTERNAL_API
michael@0 15
michael@0 16 #include "mozilla/BlockingResourceBase.h"
michael@0 17
michael@0 18 //
michael@0 19 // Provides:
michael@0 20 //
michael@0 21 // - ReentrantMonitor, a Java-like monitor
michael@0 22 // - ReentrantMonitorAutoEnter, an RAII class for ensuring that
michael@0 23 // ReentrantMonitors are properly entered and exited
michael@0 24 //
michael@0 25 // Using ReentrantMonitorAutoEnter is MUCH preferred to making bare calls to
michael@0 26 // ReentrantMonitor.Enter and Exit.
michael@0 27 //
michael@0 28 namespace mozilla {
michael@0 29
michael@0 30
michael@0 31 /**
michael@0 32 * ReentrantMonitor
michael@0 33 * Java-like monitor.
michael@0 34 * When possible, use ReentrantMonitorAutoEnter to hold this monitor within a
michael@0 35 * scope, instead of calling Enter/Exit directly.
michael@0 36 **/
michael@0 37 class NS_COM_GLUE ReentrantMonitor : BlockingResourceBase
michael@0 38 {
michael@0 39 public:
michael@0 40 /**
michael@0 41 * ReentrantMonitor
michael@0 42 * @param aName A name which can reference this monitor
michael@0 43 */
michael@0 44 ReentrantMonitor(const char* aName) :
michael@0 45 BlockingResourceBase(aName, eReentrantMonitor)
michael@0 46 #ifdef DEBUG
michael@0 47 , mEntryCount(0)
michael@0 48 #endif
michael@0 49 {
michael@0 50 MOZ_COUNT_CTOR(ReentrantMonitor);
michael@0 51 mReentrantMonitor = PR_NewMonitor();
michael@0 52 if (!mReentrantMonitor)
michael@0 53 NS_RUNTIMEABORT("Can't allocate mozilla::ReentrantMonitor");
michael@0 54 }
michael@0 55
michael@0 56 /**
michael@0 57 * ~ReentrantMonitor
michael@0 58 **/
michael@0 59 ~ReentrantMonitor()
michael@0 60 {
michael@0 61 NS_ASSERTION(mReentrantMonitor,
michael@0 62 "improperly constructed ReentrantMonitor or double free");
michael@0 63 PR_DestroyMonitor(mReentrantMonitor);
michael@0 64 mReentrantMonitor = 0;
michael@0 65 MOZ_COUNT_DTOR(ReentrantMonitor);
michael@0 66 }
michael@0 67
michael@0 68 #ifndef DEBUG
michael@0 69 /**
michael@0 70 * Enter
michael@0 71 * @see prmon.h
michael@0 72 **/
michael@0 73 void Enter()
michael@0 74 {
michael@0 75 PR_EnterMonitor(mReentrantMonitor);
michael@0 76 }
michael@0 77
michael@0 78 /**
michael@0 79 * Exit
michael@0 80 * @see prmon.h
michael@0 81 **/
michael@0 82 void Exit()
michael@0 83 {
michael@0 84 PR_ExitMonitor(mReentrantMonitor);
michael@0 85 }
michael@0 86
michael@0 87 /**
michael@0 88 * Wait
michael@0 89 * @see prmon.h
michael@0 90 **/
michael@0 91 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
michael@0 92 {
michael@0 93 #ifdef MOZILLA_INTERNAL_API
michael@0 94 GeckoProfilerSleepRAII profiler_sleep;
michael@0 95 #endif //MOZILLA_INTERNAL_API
michael@0 96 return PR_Wait(mReentrantMonitor, interval) == PR_SUCCESS ?
michael@0 97 NS_OK : NS_ERROR_FAILURE;
michael@0 98 }
michael@0 99
michael@0 100 #else // ifndef DEBUG
michael@0 101 void Enter();
michael@0 102 void Exit();
michael@0 103 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
michael@0 104
michael@0 105 #endif // ifndef DEBUG
michael@0 106
michael@0 107 /**
michael@0 108 * Notify
michael@0 109 * @see prmon.h
michael@0 110 **/
michael@0 111 nsresult Notify()
michael@0 112 {
michael@0 113 return PR_Notify(mReentrantMonitor) == PR_SUCCESS
michael@0 114 ? NS_OK : NS_ERROR_FAILURE;
michael@0 115 }
michael@0 116
michael@0 117 /**
michael@0 118 * NotifyAll
michael@0 119 * @see prmon.h
michael@0 120 **/
michael@0 121 nsresult NotifyAll()
michael@0 122 {
michael@0 123 return PR_NotifyAll(mReentrantMonitor) == PR_SUCCESS
michael@0 124 ? NS_OK : NS_ERROR_FAILURE;
michael@0 125 }
michael@0 126
michael@0 127 #ifdef DEBUG
michael@0 128 /**
michael@0 129 * AssertCurrentThreadIn
michael@0 130 * @see prmon.h
michael@0 131 **/
michael@0 132 void AssertCurrentThreadIn()
michael@0 133 {
michael@0 134 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mReentrantMonitor);
michael@0 135 }
michael@0 136
michael@0 137 /**
michael@0 138 * AssertNotCurrentThreadIn
michael@0 139 * @see prmon.h
michael@0 140 **/
michael@0 141 void AssertNotCurrentThreadIn()
michael@0 142 {
michael@0 143 // FIXME bug 476536
michael@0 144 }
michael@0 145
michael@0 146 #else
michael@0 147 void AssertCurrentThreadIn()
michael@0 148 {
michael@0 149 }
michael@0 150 void AssertNotCurrentThreadIn()
michael@0 151 {
michael@0 152 }
michael@0 153
michael@0 154 #endif // ifdef DEBUG
michael@0 155
michael@0 156 private:
michael@0 157 ReentrantMonitor();
michael@0 158 ReentrantMonitor(const ReentrantMonitor&);
michael@0 159 ReentrantMonitor& operator =(const ReentrantMonitor&);
michael@0 160
michael@0 161 PRMonitor* mReentrantMonitor;
michael@0 162 #ifdef DEBUG
michael@0 163 int32_t mEntryCount;
michael@0 164 #endif
michael@0 165 };
michael@0 166
michael@0 167
michael@0 168 /**
michael@0 169 * ReentrantMonitorAutoEnter
michael@0 170 * Enters the ReentrantMonitor when it enters scope, and exits it when
michael@0 171 * it leaves scope.
michael@0 172 *
michael@0 173 * MUCH PREFERRED to bare calls to ReentrantMonitor.Enter and Exit.
michael@0 174 */
michael@0 175 class NS_COM_GLUE MOZ_STACK_CLASS ReentrantMonitorAutoEnter
michael@0 176 {
michael@0 177 public:
michael@0 178 /**
michael@0 179 * Constructor
michael@0 180 * The constructor aquires the given lock. The destructor
michael@0 181 * releases the lock.
michael@0 182 *
michael@0 183 * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*.
michael@0 184 **/
michael@0 185 ReentrantMonitorAutoEnter(mozilla::ReentrantMonitor &aReentrantMonitor) :
michael@0 186 mReentrantMonitor(&aReentrantMonitor)
michael@0 187 {
michael@0 188 NS_ASSERTION(mReentrantMonitor, "null monitor");
michael@0 189 mReentrantMonitor->Enter();
michael@0 190 }
michael@0 191
michael@0 192 ~ReentrantMonitorAutoEnter(void)
michael@0 193 {
michael@0 194 mReentrantMonitor->Exit();
michael@0 195 }
michael@0 196
michael@0 197 nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
michael@0 198 {
michael@0 199 return mReentrantMonitor->Wait(interval);
michael@0 200 }
michael@0 201
michael@0 202 nsresult Notify()
michael@0 203 {
michael@0 204 return mReentrantMonitor->Notify();
michael@0 205 }
michael@0 206
michael@0 207 nsresult NotifyAll()
michael@0 208 {
michael@0 209 return mReentrantMonitor->NotifyAll();
michael@0 210 }
michael@0 211
michael@0 212 private:
michael@0 213 ReentrantMonitorAutoEnter();
michael@0 214 ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
michael@0 215 ReentrantMonitorAutoEnter& operator =(const ReentrantMonitorAutoEnter&);
michael@0 216 static void* operator new(size_t) CPP_THROW_NEW;
michael@0 217 static void operator delete(void*);
michael@0 218
michael@0 219 mozilla::ReentrantMonitor* mReentrantMonitor;
michael@0 220 };
michael@0 221
michael@0 222 /**
michael@0 223 * ReentrantMonitorAutoExit
michael@0 224 * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves
michael@0 225 * scope.
michael@0 226 *
michael@0 227 * MUCH PREFERRED to bare calls to ReentrantMonitor.Exit and Enter.
michael@0 228 */
michael@0 229 class MOZ_STACK_CLASS ReentrantMonitorAutoExit
michael@0 230 {
michael@0 231 public:
michael@0 232 /**
michael@0 233 * Constructor
michael@0 234 * The constructor releases the given lock. The destructor
michael@0 235 * acquires the lock. The lock must be held before constructing
michael@0 236 * this object!
michael@0 237 *
michael@0 238 * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. It
michael@0 239 * must be already locked.
michael@0 240 **/
michael@0 241 ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor) :
michael@0 242 mReentrantMonitor(&aReentrantMonitor)
michael@0 243 {
michael@0 244 NS_ASSERTION(mReentrantMonitor, "null monitor");
michael@0 245 mReentrantMonitor->AssertCurrentThreadIn();
michael@0 246 mReentrantMonitor->Exit();
michael@0 247 }
michael@0 248
michael@0 249 ~ReentrantMonitorAutoExit(void)
michael@0 250 {
michael@0 251 mReentrantMonitor->Enter();
michael@0 252 }
michael@0 253
michael@0 254 private:
michael@0 255 ReentrantMonitorAutoExit();
michael@0 256 ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);
michael@0 257 ReentrantMonitorAutoExit& operator =(const ReentrantMonitorAutoExit&);
michael@0 258 static void* operator new(size_t) CPP_THROW_NEW;
michael@0 259 static void operator delete(void*);
michael@0 260
michael@0 261 ReentrantMonitor* mReentrantMonitor;
michael@0 262 };
michael@0 263
michael@0 264 } // namespace mozilla
michael@0 265
michael@0 266
michael@0 267 #endif // ifndef mozilla_ReentrantMonitor_h

mercurial