xpcom/base/StaticMutex.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 #ifndef mozilla_StaticMutex_h
michael@0 2 #define mozilla_StaticMutex_h
michael@0 3
michael@0 4 #include "mozilla/Atomics.h"
michael@0 5 #include "mozilla/Mutex.h"
michael@0 6
michael@0 7 namespace mozilla {
michael@0 8
michael@0 9 /**
michael@0 10 * StaticMutex is a Mutex that can (and in fact, must) be used as a
michael@0 11 * global/static variable.
michael@0 12 *
michael@0 13 * The main reason to use StaticMutex as opposed to
michael@0 14 * StaticAutoPtr<OffTheBooksMutex> is that we instantiate the StaticMutex in a
michael@0 15 * thread-safe manner the first time it's used.
michael@0 16 *
michael@0 17 * The same caveats that apply to StaticAutoPtr apply to StaticMutex. In
michael@0 18 * particular, do not use StaticMutex as a stack variable or a class instance
michael@0 19 * variable, because this class relies on the fact that global variablies are
michael@0 20 * initialized to 0 in order to initialize mMutex. It is only safe to use
michael@0 21 * StaticMutex as a global or static variable.
michael@0 22 */
michael@0 23 class StaticMutex
michael@0 24 {
michael@0 25 public:
michael@0 26 // In debug builds, check that mMutex is initialized for us as we expect by
michael@0 27 // the compiler. In non-debug builds, don't declare a constructor so that
michael@0 28 // the compiler can see that the constructor is trivial.
michael@0 29 #ifdef DEBUG
michael@0 30 StaticMutex()
michael@0 31 {
michael@0 32 MOZ_ASSERT(!mMutex);
michael@0 33 }
michael@0 34 #endif
michael@0 35
michael@0 36 void Lock()
michael@0 37 {
michael@0 38 Mutex()->Lock();
michael@0 39 }
michael@0 40
michael@0 41 void Unlock()
michael@0 42 {
michael@0 43 Mutex()->Unlock();
michael@0 44 }
michael@0 45
michael@0 46 void AssertCurrentThreadOwns()
michael@0 47 {
michael@0 48 #ifdef DEBUG
michael@0 49 Mutex()->AssertCurrentThreadOwns();
michael@0 50 #endif
michael@0 51 }
michael@0 52
michael@0 53 private:
michael@0 54 OffTheBooksMutex* Mutex()
michael@0 55 {
michael@0 56 if (mMutex) {
michael@0 57 return mMutex;
michael@0 58 }
michael@0 59
michael@0 60 OffTheBooksMutex* mutex = new OffTheBooksMutex("StaticMutex");
michael@0 61 if (!mMutex.compareExchange(nullptr, mutex)) {
michael@0 62 delete mutex;
michael@0 63 }
michael@0 64
michael@0 65 return mMutex;
michael@0 66 }
michael@0 67
michael@0 68 Atomic<OffTheBooksMutex*> mMutex;
michael@0 69
michael@0 70
michael@0 71 // Disallow copy constructor, but only in debug mode. We only define
michael@0 72 // a default constructor in debug mode (see above); if we declared
michael@0 73 // this constructor always, the compiler wouldn't generate a trivial
michael@0 74 // default constructor for us in non-debug mode.
michael@0 75 #ifdef DEBUG
michael@0 76 StaticMutex(StaticMutex &other);
michael@0 77 #endif
michael@0 78
michael@0 79 // Disallow these operators.
michael@0 80 StaticMutex& operator=(StaticMutex* rhs);
michael@0 81 static void* operator new(size_t) CPP_THROW_NEW;
michael@0 82 static void operator delete(void*);
michael@0 83 };
michael@0 84
michael@0 85 typedef BaseAutoLock<StaticMutex> StaticMutexAutoLock;
michael@0 86 typedef BaseAutoUnlock<StaticMutex> StaticMutexAutoUnlock;
michael@0 87
michael@0 88 } // namespace mozilla
michael@0 89
michael@0 90 #endif

mercurial