Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/re2/util/mutex.h

Issue 1544433002: Replace RE2 import with a dependency (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Re-Added LICENSE and OWNERS file Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/re2/util/logging.cc ('k') | third_party/re2/util/pcre.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2007 The RE2 Authors. All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 /*
6 * A simple mutex wrapper, supporting locks and read-write locks.
7 * You should assume the locks are *not* re-entrant.
8 */
9
10 #ifndef RE2_UTIL_MUTEX_H_
11 #define RE2_UTIL_MUTEX_H_
12
13 #include <stdlib.h>
14
15 #if !defined(_WIN32)
16 #include <unistd.h> // For POSIX options
17 #endif
18
19 namespace re2 {
20
21 #if !defined(_WIN32)
22 // Possible values of POSIX options:
23 // -1 means not supported,
24 // 0 means maybe supported (query at runtime),
25 // >0 means supported.
26 # if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
27 # define HAVE_PTHREAD 1
28 # else
29 # define HAVE_PTHREAD 0
30 # endif
31 # if defined(_POSIX_READER_WRITER_LOCKS) && _POSIX_READER_WRITER_LOCKS > 0
32 # define HAVE_RWLOCK 1
33 # else
34 # define HAVE_RWLOCK 0
35 # endif
36 #else
37 # define HAVE_PTHREAD 0
38 # define HAVE_RWLOCK 0
39 #endif
40
41 #if defined(NO_THREADS)
42 typedef int MutexType; // to keep a lock-count
43 #elif HAVE_PTHREAD && HAVE_RWLOCK
44 // Needed for pthread_rwlock_*. If it causes problems, you could take it
45 // out, but then you'd have to set HAVE_RWLOCK to 0 (at least on linux --
46 // it *does* cause problems for FreeBSD, or MacOSX, but isn't needed
47 // for locking there.)
48 # ifdef __linux__
49 # undef _XOPEN_SOURCE
50 # define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
51 # endif
52 # include <pthread.h>
53 typedef pthread_rwlock_t MutexType;
54 #elif HAVE_PTHREAD
55 # include <pthread.h>
56 typedef pthread_mutex_t MutexType;
57 #elif defined(_WIN32)
58 # ifndef WIN32_LEAN_AND_MEAN
59 # define WIN32_LEAN_AND_MEAN // We only need minimal includes
60 # endif
61 # ifdef GMUTEX_TRYLOCK
62 // We need Windows NT or later for TryEnterCriticalSection(). If you
63 // don't need that functionality, you can remove these _WIN32_WINNT
64 // lines, and change TryLock() to assert(0) or something.
65 # ifndef _WIN32_WINNT
66 # define _WIN32_WINNT 0x0400
67 # endif
68 # endif
69 # include <windows.h>
70 typedef CRITICAL_SECTION MutexType;
71 #else
72 # error Need to implement mutex.h for your architecture, or #define NO_THREADS
73 #endif
74
75 class Mutex {
76 public:
77 // Create a Mutex that is not held by anybody.
78 inline Mutex();
79
80 // Destructor
81 inline ~Mutex();
82
83 inline void Lock(); // Block if needed until free then acquire exclusively
84 inline void Unlock(); // Release a lock acquired via Lock()
85 inline bool TryLock(); // If free, Lock() and return true, else return false
86 // Note that on systems that don't support read-write locks, these may
87 // be implemented as synonyms to Lock() and Unlock(). So you can use
88 // these for efficiency, but don't use them anyplace where being able
89 // to do shared reads is necessary to avoid deadlock.
90 inline void ReaderLock(); // Block until free or shared then acquire a share
91 inline void ReaderUnlock(); // Release a read share of this Mutex
92 inline void WriterLock() { Lock(); } // Acquire an exclusive lock
93 inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
94 inline void AssertHeld() { }
95
96 private:
97 MutexType mutex_;
98
99 // Catch the error of writing Mutex when intending MutexLock.
100 Mutex(Mutex *ignored);
101 // Disallow "evil" constructors
102 Mutex(const Mutex&);
103 void operator=(const Mutex&);
104 };
105
106 // Now the implementation of Mutex for various systems
107 #if defined(NO_THREADS)
108
109 // When we don't have threads, we can be either reading or writing,
110 // but not both. We can have lots of readers at once (in no-threads
111 // mode, that's most likely to happen in recursive function calls),
112 // but only one writer. We represent this by having mutex_ be -1 when
113 // writing and a number > 0 when reading (and 0 when no lock is held).
114 //
115 // In debug mode, we assert these invariants, while in non-debug mode
116 // we do nothing, for efficiency. That's why everything is in an
117 // assert.
118 #include <assert.h>
119
120 Mutex::Mutex() : mutex_(0) { }
121 Mutex::~Mutex() { assert(mutex_ == 0); }
122 void Mutex::Lock() { assert(--mutex_ == -1); }
123 void Mutex::Unlock() { assert(mutex_++ == -1); }
124 bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
125 void Mutex::ReaderLock() { assert(++mutex_ > 0); }
126 void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
127
128 #elif HAVE_PTHREAD && HAVE_RWLOCK
129
130 #define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
131
132 Mutex::Mutex() { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); }
133 Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); }
134 void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); }
135 void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
136 bool Mutex::TryLock() { return pthread_rwlock_trywrlock(&mutex_) == 0; }
137 void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); }
138 void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
139
140 #undef SAFE_PTHREAD
141
142 #elif HAVE_PTHREAD
143
144 #define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
145
146 Mutex::Mutex() { SAFE_PTHREAD(pthread_mutex_init(&mutex_, NULL)); }
147 Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy(&mutex_)); }
148 void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock(&mutex_)); }
149 void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&mutex_)); }
150 bool Mutex::TryLock() { return pthread_mutex_trylock(&mutex_) == 0; }
151 void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
152 void Mutex::ReaderUnlock() { Unlock(); }
153 #undef SAFE_PTHREAD
154
155 #elif defined(_WIN32)
156
157 Mutex::Mutex() { InitializeCriticalSection(&mutex_); }
158 Mutex::~Mutex() { DeleteCriticalSection(&mutex_); }
159 void Mutex::Lock() { EnterCriticalSection(&mutex_); }
160 void Mutex::Unlock() { LeaveCriticalSection(&mutex_); }
161 bool Mutex::TryLock() { return TryEnterCriticalSection(&mutex_) != 0; }
162 void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
163 void Mutex::ReaderUnlock() { Unlock(); }
164
165 #endif
166
167
168 // --------------------------------------------------------------------------
169 // Some helper classes
170
171 // MutexLock(mu) acquires mu when constructed and releases it when destroyed.
172 class MutexLock {
173 public:
174 explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
175 ~MutexLock() { mu_->Unlock(); }
176 private:
177 Mutex * const mu_;
178 // Disallow "evil" constructors
179 MutexLock(const MutexLock&);
180 void operator=(const MutexLock&);
181 };
182
183 // ReaderMutexLock and WriterMutexLock do the same, for rwlocks
184 class ReaderMutexLock {
185 public:
186 explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
187 ~ReaderMutexLock() { mu_->ReaderUnlock(); }
188 private:
189 Mutex * const mu_;
190 // Disallow "evil" constructors
191 ReaderMutexLock(const ReaderMutexLock&);
192 void operator=(const ReaderMutexLock&);
193 };
194
195 class WriterMutexLock {
196 public:
197 explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
198 ~WriterMutexLock() { mu_->WriterUnlock(); }
199 private:
200 Mutex * const mu_;
201 // Disallow "evil" constructors
202 WriterMutexLock(const WriterMutexLock&);
203 void operator=(const WriterMutexLock&);
204 };
205
206 // Catch bug where variable name is omitted, e.g. MutexLock (&mu);
207 #define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
208 #define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
209 #define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
210
211 // Provide safe way to declare and use global, linker-initialized mutex. Sigh.
212 #if HAVE_PTHREAD
213
214 #define GLOBAL_MUTEX(name) \
215 static pthread_mutex_t (name) = PTHREAD_MUTEX_INITIALIZER
216 #define GLOBAL_MUTEX_LOCK(name) \
217 pthread_mutex_lock(&(name))
218 #define GLOBAL_MUTEX_UNLOCK(name) \
219 pthread_mutex_unlock(&(name))
220
221 #else
222
223 #define GLOBAL_MUTEX(name) \
224 static Mutex name
225 #define GLOBAL_MUTEX_LOCK(name) \
226 name.Lock()
227 #define GLOBAL_MUTEX_UNLOCK(name) \
228 name.Unlock()
229
230 #endif
231
232 } // namespace re2
233
234 #endif /* #define RE2_UTIL_MUTEX_H_ */
OLDNEW
« no previous file with comments | « third_party/re2/util/logging.cc ('k') | third_party/re2/util/pcre.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698