The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.
Please select the desired protocol below to get the URL.
This URL has Read-Only access.
main_repo / deps / v8 / src / platform / mutex.h @ f230a1cf
History | View | Annotate | Download (8.23 KB)
1 |
// Copyright 2013 the V8 project authors. All rights reserved.
|
---|---|
2 |
// Redistribution and use in source and binary forms, with or without
|
3 |
// modification, are permitted provided that the following conditions are
|
4 |
// met:
|
5 |
//
|
6 |
// * Redistributions of source code must retain the above copyright
|
7 |
// notice, this list of conditions and the following disclaimer.
|
8 |
// * Redistributions in binary form must reproduce the above
|
9 |
// copyright notice, this list of conditions and the following
|
10 |
// disclaimer in the documentation and/or other materials provided
|
11 |
// with the distribution.
|
12 |
// * Neither the name of Google Inc. nor the names of its
|
13 |
// contributors may be used to endorse or promote products derived
|
14 |
// from this software without specific prior written permission.
|
15 |
//
|
16 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
18 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
19 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
20 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
|
28 |
#ifndef V8_PLATFORM_MUTEX_H_
|
29 |
#define V8_PLATFORM_MUTEX_H_
|
30 |
|
31 |
#include "../lazy-instance.h" |
32 |
#if V8_OS_WIN
|
33 |
#include "../win32-headers.h" |
34 |
#endif
|
35 |
|
36 |
#if V8_OS_POSIX
|
37 |
#include <pthread.h> // NOLINT |
38 |
#endif
|
39 |
|
40 |
namespace v8 { |
41 |
namespace internal { |
42 |
|
43 |
// ----------------------------------------------------------------------------
|
44 |
// Mutex
|
45 |
//
|
46 |
// This class is a synchronization primitive that can be used to protect shared
|
47 |
// data from being simultaneously accessed by multiple threads. A mutex offers
|
48 |
// exclusive, non-recursive ownership semantics:
|
49 |
// - A calling thread owns a mutex from the time that it successfully calls
|
50 |
// either |Lock()| or |TryLock()| until it calls |Unlock()|.
|
51 |
// - When a thread owns a mutex, all other threads will block (for calls to
|
52 |
// |Lock()|) or receive a |false| return value (for |TryLock()|) if they
|
53 |
// attempt to claim ownership of the mutex.
|
54 |
// A calling thread must not own the mutex prior to calling |Lock()| or
|
55 |
// |TryLock()|. The behavior of a program is undefined if a mutex is destroyed
|
56 |
// while still owned by some thread. The Mutex class is non-copyable.
|
57 |
|
58 |
class Mutex V8_FINAL { |
59 |
public:
|
60 |
Mutex(); |
61 |
~Mutex(); |
62 |
|
63 |
// Locks the given mutex. If the mutex is currently unlocked, it becomes
|
64 |
// locked and owned by the calling thread, and immediately. If the mutex
|
65 |
// is already locked by another thread, suspends the calling thread until
|
66 |
// the mutex is unlocked.
|
67 |
void Lock();
|
68 |
|
69 |
// Unlocks the given mutex. The mutex is assumed to be locked and owned by
|
70 |
// the calling thread on entrance.
|
71 |
void Unlock();
|
72 |
|
73 |
// Tries to lock the given mutex. Returns whether the mutex was
|
74 |
// successfully locked.
|
75 |
bool TryLock() V8_WARN_UNUSED_RESULT;
|
76 |
|
77 |
// The implementation-defined native handle type.
|
78 |
#if V8_OS_POSIX
|
79 |
typedef pthread_mutex_t NativeHandle;
|
80 |
#elif V8_OS_WIN
|
81 |
typedef CRITICAL_SECTION NativeHandle;
|
82 |
#endif
|
83 |
|
84 |
NativeHandle& native_handle() { |
85 |
return native_handle_;
|
86 |
} |
87 |
const NativeHandle& native_handle() const { |
88 |
return native_handle_;
|
89 |
} |
90 |
|
91 |
private:
|
92 |
NativeHandle native_handle_; |
93 |
#ifdef DEBUG
|
94 |
int level_;
|
95 |
#endif
|
96 |
|
97 |
V8_INLINE void AssertHeldAndUnmark() {
|
98 |
#ifdef DEBUG
|
99 |
ASSERT_EQ(1, level_);
|
100 |
level_--; |
101 |
#endif
|
102 |
} |
103 |
|
104 |
V8_INLINE void AssertUnheldAndMark() {
|
105 |
#ifdef DEBUG
|
106 |
ASSERT_EQ(0, level_);
|
107 |
level_++; |
108 |
#endif
|
109 |
} |
110 |
|
111 |
friend class ConditionVariable; |
112 |
|
113 |
DISALLOW_COPY_AND_ASSIGN(Mutex); |
114 |
}; |
115 |
|
116 |
|
117 |
// POD Mutex initialized lazily (i.e. the first time Pointer() is called).
|
118 |
// Usage:
|
119 |
// static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER;
|
120 |
//
|
121 |
// void my_function() {
|
122 |
// LockGuard<Mutex> guard(my_mutex.Pointer());
|
123 |
// // Do something.
|
124 |
// }
|
125 |
//
|
126 |
typedef LazyStaticInstance<Mutex,
|
127 |
DefaultConstructTrait<Mutex>, |
128 |
ThreadSafeInitOnceTrait>::type LazyMutex; |
129 |
|
130 |
#define LAZY_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
|
131 |
|
132 |
|
133 |
// -----------------------------------------------------------------------------
|
134 |
// RecursiveMutex
|
135 |
//
|
136 |
// This class is a synchronization primitive that can be used to protect shared
|
137 |
// data from being simultaneously accessed by multiple threads. A recursive
|
138 |
// mutex offers exclusive, recursive ownership semantics:
|
139 |
// - A calling thread owns a recursive mutex for a period of time that starts
|
140 |
// when it successfully calls either |Lock()| or |TryLock()|. During this
|
141 |
// period, the thread may make additional calls to |Lock()| or |TryLock()|.
|
142 |
// The period of ownership ends when the thread makes a matching number of
|
143 |
// calls to |Unlock()|.
|
144 |
// - When a thread owns a recursive mutex, all other threads will block (for
|
145 |
// calls to |Lock()|) or receive a |false| return value (for |TryLock()|) if
|
146 |
// they attempt to claim ownership of the recursive mutex.
|
147 |
// - The maximum number of times that a recursive mutex may be locked is
|
148 |
// unspecified, but after that number is reached, calls to |Lock()| will
|
149 |
// probably abort the process and calls to |TryLock()| return false.
|
150 |
// The behavior of a program is undefined if a recursive mutex is destroyed
|
151 |
// while still owned by some thread. The RecursiveMutex class is non-copyable.
|
152 |
|
153 |
class RecursiveMutex V8_FINAL { |
154 |
public:
|
155 |
RecursiveMutex(); |
156 |
~RecursiveMutex(); |
157 |
|
158 |
// Locks the mutex. If another thread has already locked the mutex, a call to
|
159 |
// |Lock()| will block execution until the lock is acquired. A thread may call
|
160 |
// |Lock()| on a recursive mutex repeatedly. Ownership will only be released
|
161 |
// after the thread makes a matching number of calls to |Unlock()|.
|
162 |
// The behavior is undefined if the mutex is not unlocked before being
|
163 |
// destroyed, i.e. some thread still owns it.
|
164 |
void Lock();
|
165 |
|
166 |
// Unlocks the mutex if its level of ownership is 1 (there was exactly one
|
167 |
// more call to |Lock()| than there were calls to unlock() made by this
|
168 |
// thread), reduces the level of ownership by 1 otherwise. The mutex must be
|
169 |
// locked by the current thread of execution, otherwise, the behavior is
|
170 |
// undefined.
|
171 |
void Unlock();
|
172 |
|
173 |
// Tries to lock the given mutex. Returns whether the mutex was
|
174 |
// successfully locked.
|
175 |
bool TryLock() V8_WARN_UNUSED_RESULT;
|
176 |
|
177 |
// The implementation-defined native handle type.
|
178 |
typedef Mutex::NativeHandle NativeHandle;
|
179 |
|
180 |
NativeHandle& native_handle() { |
181 |
return native_handle_;
|
182 |
} |
183 |
const NativeHandle& native_handle() const { |
184 |
return native_handle_;
|
185 |
} |
186 |
|
187 |
private:
|
188 |
NativeHandle native_handle_; |
189 |
#ifdef DEBUG
|
190 |
int level_;
|
191 |
#endif
|
192 |
|
193 |
DISALLOW_COPY_AND_ASSIGN(RecursiveMutex); |
194 |
}; |
195 |
|
196 |
|
197 |
// POD RecursiveMutex initialized lazily (i.e. the first time Pointer() is
|
198 |
// called).
|
199 |
// Usage:
|
200 |
// static LazyRecursiveMutex my_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
|
201 |
//
|
202 |
// void my_function() {
|
203 |
// LockGuard<RecursiveMutex> guard(my_mutex.Pointer());
|
204 |
// // Do something.
|
205 |
// }
|
206 |
//
|
207 |
typedef LazyStaticInstance<RecursiveMutex,
|
208 |
DefaultConstructTrait<RecursiveMutex>, |
209 |
ThreadSafeInitOnceTrait>::type LazyRecursiveMutex; |
210 |
|
211 |
#define LAZY_RECURSIVE_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
|
212 |
|
213 |
|
214 |
// -----------------------------------------------------------------------------
|
215 |
// LockGuard
|
216 |
//
|
217 |
// This class is a mutex wrapper that provides a convenient RAII-style mechanism
|
218 |
// for owning a mutex for the duration of a scoped block.
|
219 |
// When a LockGuard object is created, it attempts to take ownership of the
|
220 |
// mutex it is given. When control leaves the scope in which the LockGuard
|
221 |
// object was created, the LockGuard is destructed and the mutex is released.
|
222 |
// The LockGuard class is non-copyable.
|
223 |
|
224 |
template <typename Mutex> |
225 |
class LockGuard V8_FINAL { |
226 |
public:
|
227 |
explicit LockGuard(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } |
228 |
~LockGuard() { mutex_->Unlock(); } |
229 |
|
230 |
private:
|
231 |
Mutex* mutex_; |
232 |
|
233 |
DISALLOW_COPY_AND_ASSIGN(LockGuard); |
234 |
}; |
235 |
|
236 |
} } // namespace v8::internal
|
237 |
|
238 |
#endif // V8_PLATFORM_MUTEX_H_ |