Bug 1842773 - Part 16: Replace TypedArrayObject with FixedLengthTypedArrayObject...
[gecko.git] / xpcom / base / StaticMonitor.h
blobb35d3871d2e1462fad56781763df39c19999ca29
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/. */
7 #ifndef mozilla_StaticMonitor_h
8 #define mozilla_StaticMonitor_h
10 #include "mozilla/Atomics.h"
11 #include "mozilla/CondVar.h"
12 #include "mozilla/ThreadSafety.h"
14 namespace mozilla {
16 class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS MOZ_CAPABILITY("monitor")
17 StaticMonitor {
18 public:
19 // In debug builds, check that mMutex is initialized for us as we expect by
20 // the compiler. In non-debug builds, don't declare a constructor so that
21 // the compiler can see that the constructor is trivial.
22 #ifdef DEBUG
23 StaticMonitor() { MOZ_ASSERT(!mMutex); }
24 #endif
26 void Lock() MOZ_CAPABILITY_ACQUIRE() { Mutex()->Lock(); }
28 void Unlock() MOZ_CAPABILITY_RELEASE() { Mutex()->Unlock(); }
30 void Wait() { CondVar()->Wait(); }
31 CVStatus Wait(TimeDuration aDuration) {
32 AssertCurrentThreadOwns();
33 return CondVar()->Wait(aDuration);
36 void Notify() { CondVar()->Notify(); }
37 void NotifyAll() { CondVar()->NotifyAll(); }
39 void AssertCurrentThreadOwns() MOZ_ASSERT_CAPABILITY(this) {
40 #ifdef DEBUG
41 Mutex()->AssertCurrentThreadOwns();
42 #endif
45 private:
46 OffTheBooksMutex* Mutex() {
47 if (mMutex) {
48 return mMutex;
51 OffTheBooksMutex* mutex = new OffTheBooksMutex("StaticMutex");
52 if (!mMutex.compareExchange(nullptr, mutex)) {
53 delete mutex;
56 return mMutex;
59 OffTheBooksCondVar* CondVar() {
60 if (mCondVar) {
61 return mCondVar;
64 OffTheBooksCondVar* condvar =
65 new OffTheBooksCondVar(*Mutex(), "StaticCondVar");
66 if (!mCondVar.compareExchange(nullptr, condvar)) {
67 delete condvar;
70 return mCondVar;
73 Atomic<OffTheBooksMutex*> mMutex;
74 Atomic<OffTheBooksCondVar*> mCondVar;
76 // Disallow copy constructor, but only in debug mode. We only define
77 // a default constructor in debug mode (see above); if we declared
78 // this constructor always, the compiler wouldn't generate a trivial
79 // default constructor for us in non-debug mode.
80 #ifdef DEBUG
81 StaticMonitor(const StaticMonitor& aOther);
82 #endif
84 // Disallow these operators.
85 StaticMonitor& operator=(const StaticMonitor& aRhs);
86 static void* operator new(size_t) noexcept(true);
87 static void operator delete(void*);
90 class MOZ_STACK_CLASS MOZ_SCOPED_CAPABILITY StaticMonitorAutoLock {
91 public:
92 explicit StaticMonitorAutoLock(StaticMonitor& aMonitor)
93 MOZ_CAPABILITY_ACQUIRE(aMonitor)
94 : mMonitor(&aMonitor) {
95 mMonitor->Lock();
98 ~StaticMonitorAutoLock() MOZ_CAPABILITY_RELEASE() { mMonitor->Unlock(); }
100 void Wait() { mMonitor->Wait(); }
101 CVStatus Wait(TimeDuration aDuration) { return mMonitor->Wait(aDuration); }
103 void Notify() { mMonitor->Notify(); }
104 void NotifyAll() { mMonitor->NotifyAll(); }
106 private:
107 StaticMonitorAutoLock();
108 StaticMonitorAutoLock(const StaticMonitorAutoLock&);
109 StaticMonitorAutoLock& operator=(const StaticMonitorAutoLock&);
110 static void* operator new(size_t) noexcept(true);
112 StaticMonitor* mMonitor;
115 } // namespace mozilla
117 #endif