Bug 1586807 - Make pseudoclass locking work with Fission. r=pbro
[gecko.git] / xpcom / threads / Monitor.h
blob772087c480fb05720fae61ef20c845bb2d850a80
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, recordreplay::Behavior aRecorded =
27 recordreplay::Behavior::Preserve)
28 : mMutex(aName, aRecorded), mCondVar(mMutex, "[Monitor.mCondVar]") {}
30 ~Monitor() {}
32 void Lock() { mMutex.Lock(); }
33 bool TryLock() { return mMutex.TryLock(); }
34 void Unlock() { mMutex.Unlock(); }
36 void Wait() { mCondVar.Wait(); }
37 CVStatus Wait(TimeDuration aDuration) { return mCondVar.Wait(aDuration); }
39 nsresult Notify() { return mCondVar.Notify(); }
40 nsresult NotifyAll() { return mCondVar.NotifyAll(); }
42 void AssertCurrentThreadOwns() const { mMutex.AssertCurrentThreadOwns(); }
44 void AssertNotCurrentThreadOwns() const {
45 mMutex.AssertNotCurrentThreadOwns();
48 private:
49 Monitor();
50 Monitor(const Monitor&);
51 Monitor& operator=(const Monitor&);
53 Mutex mMutex;
54 CondVar mCondVar;
57 /**
58 * Lock the monitor for the lexical scope instances of this class are
59 * bound to (except for MonitorAutoUnlock in nested scopes).
61 * The monitor must be unlocked when instances of this class are
62 * created.
64 class MOZ_STACK_CLASS MonitorAutoLock {
65 public:
66 explicit MonitorAutoLock(Monitor& aMonitor) : mMonitor(&aMonitor) {
67 mMonitor->Lock();
70 ~MonitorAutoLock() { mMonitor->Unlock(); }
72 void Wait() { mMonitor->Wait(); }
73 CVStatus Wait(TimeDuration aDuration) { return mMonitor->Wait(aDuration); }
75 nsresult Notify() { return mMonitor->Notify(); }
76 nsresult NotifyAll() { return mMonitor->NotifyAll(); }
78 private:
79 MonitorAutoLock();
80 MonitorAutoLock(const MonitorAutoLock&);
81 MonitorAutoLock& operator=(const MonitorAutoLock&);
82 static void* operator new(size_t) noexcept(true);
84 friend class MonitorAutoUnlock;
86 Monitor* mMonitor;
89 /**
90 * Unlock the monitor for the lexical scope instances of this class
91 * are bound to (except for MonitorAutoLock in nested scopes).
93 * The monitor must be locked by the current thread when instances of
94 * this class are created.
96 class MOZ_STACK_CLASS MonitorAutoUnlock {
97 public:
98 explicit MonitorAutoUnlock(Monitor& aMonitor) : mMonitor(&aMonitor) {
99 mMonitor->Unlock();
102 explicit MonitorAutoUnlock(MonitorAutoLock& aMonitorLock)
103 : mMonitor(aMonitorLock.mMonitor) {
104 mMonitor->Unlock();
107 ~MonitorAutoUnlock() { mMonitor->Lock(); }
109 private:
110 MonitorAutoUnlock();
111 MonitorAutoUnlock(const MonitorAutoUnlock&);
112 MonitorAutoUnlock& operator=(const MonitorAutoUnlock&);
113 static void* operator new(size_t) noexcept(true);
115 Monitor* mMonitor;
118 } // namespace mozilla
120 #endif // mozilla_Monitor_h