1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_CondVar_h
#define mozilla_CondVar_h
#include "mozilla/BlockingResourceBase.h"
#include "mozilla/PlatformConditionVariable.h"
#include "mozilla/Mutex.h"
#include "mozilla/TimeStamp.h"
#if defined(MOZILLA_INTERNAL_API) && !defined(DEBUG)
# include "mozilla/ProfilerThreadSleep.h"
#endif // defined( MOZILLA_INTERNAL_API) && !defined(DEBUG)
namespace mozilla {
/**
* Similarly to OffTheBooksMutex, OffTheBooksCondvar is identical to CondVar,
* except that OffTheBooksCondVar doesn't include leak checking. Sometimes
* you want to intentionally "leak" a CondVar until shutdown; in these cases,
* OffTheBooksCondVar is for you.
*/
class OffTheBooksCondVar : BlockingResourceBase {
public:
/**
* OffTheBooksCondVar
*
* The CALLER owns |aLock|.
*
* @param aLock A Mutex to associate with this condition variable.
* @param aName A name which can reference this monitor
* @returns If failure, nullptr.
* If success, a valid Monitor* which must be destroyed
* by Monitor::DestroyMonitor()
**/
OffTheBooksCondVar(OffTheBooksMutex& aLock, const char* aName)
: BlockingResourceBase(aName, eCondVar), mLock(&aLock) {}
/**
* ~OffTheBooksCondVar
* Clean up after this OffTheBooksCondVar, but NOT its associated Mutex.
**/
~OffTheBooksCondVar() = default;
/**
* Wait
* @see prcvar.h
**/
#ifndef DEBUG
void Wait() {
# ifdef MOZILLA_INTERNAL_API
AUTO_PROFILER_THREAD_SLEEP;
# endif // MOZILLA_INTERNAL_API
mImpl.wait(*mLock);
}
CVStatus Wait(TimeDuration aDuration) {
# ifdef MOZILLA_INTERNAL_API
AUTO_PROFILER_THREAD_SLEEP;
# endif // MOZILLA_INTERNAL_API
return mImpl.wait_for(*mLock, aDuration);
}
#else
// NOTE: debug impl is in BlockingResourceBase.cpp
void Wait();
CVStatus Wait(TimeDuration aDuration);
#endif
/**
* Notify
* @see prcvar.h
**/
void Notify() { mImpl.notify_one(); }
/**
* NotifyAll
* @see prcvar.h
**/
void NotifyAll() { mImpl.notify_all(); }
#ifdef DEBUG
/**
* AssertCurrentThreadOwnsMutex
* @see Mutex::AssertCurrentThreadOwns
**/
void AssertCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(mLock) {
mLock->AssertCurrentThreadOwns();
}
/**
* AssertNotCurrentThreadOwnsMutex
* @see Mutex::AssertNotCurrentThreadOwns
**/
void AssertNotCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(!mLock) {
mLock->AssertNotCurrentThreadOwns();
}
#else
void AssertCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(mLock) {}
void AssertNotCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(!mLock) {}
#endif // ifdef DEBUG
private:
OffTheBooksCondVar();
OffTheBooksCondVar(const OffTheBooksCondVar&) = delete;
OffTheBooksCondVar& operator=(const OffTheBooksCondVar&) = delete;
OffTheBooksMutex* mLock;
detail::ConditionVariableImpl mImpl;
};
/**
* CondVar
* Vanilla condition variable. Please don't use this unless you have a
* compelling reason --- Monitor provides a simpler API.
*/
class CondVar : public OffTheBooksCondVar {
public:
CondVar(OffTheBooksMutex& aLock, const char* aName)
: OffTheBooksCondVar(aLock, aName) {
MOZ_COUNT_CTOR(CondVar);
}
MOZ_COUNTED_DTOR(CondVar)
private:
CondVar();
CondVar(const CondVar&);
CondVar& operator=(const CondVar&);
};
} // namespace mozilla
#endif // ifndef mozilla_CondVar_h
|