v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mutex.h
Go to the documentation of this file.
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 
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 
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,
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 
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>,
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_
NativeHandle & native_handle()
Definition: mutex.h:84
LockGuard(Mutex *mutex)
Definition: mutex.h:227
LazyStaticInstance< Mutex, DefaultConstructTrait< Mutex >, ThreadSafeInitOnceTrait >::type LazyMutex
Definition: mutex.h:128
Mutex::NativeHandle NativeHandle
Definition: mutex.h:178
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:359
const NativeHandle & native_handle() const
Definition: mutex.h:87
#define V8_WARN_UNUSED_RESULT
Definition: v8config.h:361
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
LazyStaticInstance< RecursiveMutex, DefaultConstructTrait< RecursiveMutex >, ThreadSafeInitOnceTrait >::type LazyRecursiveMutex
Definition: mutex.h:209
#define V8_INLINE
Definition: v8config.h:316