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"
16 class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS
MOZ_CAPABILITY("monitor")
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.
23 StaticMonitor() { MOZ_ASSERT(!mMutex
); }
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) {
41 Mutex()->AssertCurrentThreadOwns();
46 OffTheBooksMutex
* Mutex() {
51 OffTheBooksMutex
* mutex
= new OffTheBooksMutex("StaticMutex");
52 if (!mMutex
.compareExchange(nullptr, mutex
)) {
59 OffTheBooksCondVar
* CondVar() {
64 OffTheBooksCondVar
* condvar
=
65 new OffTheBooksCondVar(*Mutex(), "StaticCondVar");
66 if (!mCondVar
.compareExchange(nullptr, condvar
)) {
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.
81 StaticMonitor(const StaticMonitor
& aOther
);
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
{
92 explicit StaticMonitorAutoLock(StaticMonitor
& aMonitor
)
93 MOZ_CAPABILITY_ACQUIRE(aMonitor
)
94 : mMonitor(&aMonitor
) {
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(); }
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