Bug 1693453 [wpt PR 27671] - Add test to check the unavailability of storages in...
[gecko.git] / xpcom / threads / Monitor.h
blobff8204b5adad687767e0849936530160a28098b3
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_Monitor_h
8 #define mozilla_Monitor_h
10 #include "mozilla/CondVar.h"
11 #include "mozilla/Mutex.h"
13 namespace mozilla {
15 /**
16 * Monitor provides a *non*-reentrant monitor: *not* a Java-style
17 * monitor. If your code needs support for reentrancy, use
18 * ReentrantMonitor instead. (Rarely should reentrancy be needed.)
20 * Instead of directly calling Monitor methods, it's safer and simpler
21 * to instead use the RAII wrappers MonitorAutoLock and
22 * MonitorAutoUnlock.
24 class Monitor {
25 public:
26 explicit Monitor(const char* aName)
27 : mMutex(aName), mCondVar(mMutex, "[Monitor.mCondVar]") {}
29 ~Monitor() = default;
31 void Lock() { mMutex.Lock(); }
32 [[nodiscard]] bool TryLock() { return mMutex.TryLock(); }
33 void Unlock() { mMutex.Unlock(); }
35 void Wait() { mCondVar.Wait(); }
36 CVStatus Wait(TimeDuration aDuration) { return mCondVar.Wait(aDuration); }
38 void Notify() { mCondVar.Notify(); }
39 void NotifyAll() { mCondVar.NotifyAll(); }
41 void AssertCurrentThreadOwns() const { mMutex.AssertCurrentThreadOwns(); }
43 void AssertNotCurrentThreadOwns() const {
44 mMutex.AssertNotCurrentThreadOwns();
47 private:
48 Monitor();
49 Monitor(const Monitor&);
50 Monitor& operator=(const Monitor&);
52 Mutex mMutex;
53 CondVar mCondVar;
56 /**
57 * Lock the monitor for the lexical scope instances of this class are
58 * bound to (except for MonitorAutoUnlock in nested scopes).
60 * The monitor must be unlocked when instances of this class are
61 * created.
63 class MOZ_STACK_CLASS MonitorAutoLock {
64 public:
65 explicit MonitorAutoLock(Monitor& aMonitor) : mMonitor(&aMonitor) {
66 mMonitor->Lock();
69 ~MonitorAutoLock() { mMonitor->Unlock(); }
71 void Wait() { mMonitor->Wait(); }
72 CVStatus Wait(TimeDuration aDuration) { return mMonitor->Wait(aDuration); }
74 void Notify() { mMonitor->Notify(); }
75 void NotifyAll() { mMonitor->NotifyAll(); }
77 private:
78 MonitorAutoLock();
79 MonitorAutoLock(const MonitorAutoLock&);
80 MonitorAutoLock& operator=(const MonitorAutoLock&);
81 static void* operator new(size_t) noexcept(true);
83 friend class MonitorAutoUnlock;
85 Monitor* mMonitor;
88 /**
89 * Unlock the monitor for the lexical scope instances of this class
90 * are bound to (except for MonitorAutoLock in nested scopes).
92 * The monitor must be locked by the current thread when instances of
93 * this class are created.
95 class MOZ_STACK_CLASS MonitorAutoUnlock {
96 public:
97 explicit MonitorAutoUnlock(Monitor& aMonitor) : mMonitor(&aMonitor) {
98 mMonitor->Unlock();
101 explicit MonitorAutoUnlock(MonitorAutoLock& aMonitorLock)
102 : mMonitor(aMonitorLock.mMonitor) {
103 mMonitor->Unlock();
106 ~MonitorAutoUnlock() { mMonitor->Lock(); }
108 private:
109 MonitorAutoUnlock();
110 MonitorAutoUnlock(const MonitorAutoUnlock&);
111 MonitorAutoUnlock& operator=(const MonitorAutoUnlock&);
112 static void* operator new(size_t) noexcept(true);
114 Monitor* mMonitor;
117 } // namespace mozilla
119 #endif // mozilla_Monitor_h