OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ | 5 #ifndef CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ |
6 #define CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ | 6 #define CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ |
7 | 7 |
8 #include <pthread.h> | 8 #include <pthread.h> |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
11 | 11 |
12 #ifdef OS_WIN | 12 #ifdef OS_WIN |
13 typedef void* thread_handle; | 13 typedef void* thread_handle; |
14 #else | 14 #else |
15 typedef pthread_t thread_handle; | 15 typedef pthread_t thread_handle; |
16 #endif | 16 #endif |
17 | 17 |
18 // Creates a pthread, detaches from it, and returns a Win32 HANDLE for it that | 18 // Creates a pthread, detaches from it, and returns a Win32 HANDLE for it that |
19 // the caller must CloseHandle(). | 19 // the caller must CloseHandle(). |
20 thread_handle CreatePThread(void* (*start)(void* payload), void* parameter); | 20 thread_handle CreatePThread(void* (*start)(void* payload), void* parameter); |
21 | 21 |
22 class PThreadRWLock { | |
23 public: | |
24 inline PThreadRWLock() { | |
25 int result = pthread_rwlock_init(&rwlock_, 0); | |
26 DCHECK_EQ(0, result); | |
27 } | |
28 ~PThreadRWLock() { | |
29 int result = pthread_rwlock_destroy(&rwlock_); | |
30 DCHECK_EQ(0, result); | |
31 } | |
32 pthread_rwlock_t rwlock_; | |
33 | |
34 DISALLOW_COPY_AND_ASSIGN(PThreadRWLock); | |
35 }; | |
36 | |
37 // ScopedReadLock attempts to acquire a write lock in its constructor and then | |
38 // releases it in its destructor. | |
39 class ScopedWriteLock { | |
40 public: | |
41 explicit ScopedWriteLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) { | |
42 int result = pthread_rwlock_wrlock(rwlock_); | |
43 DCHECK_EQ(0, result); | |
44 } | |
45 | |
46 explicit ScopedWriteLock(PThreadRWLock* rwlock) : rwlock_(&rwlock->rwlock_) { | |
47 int result = pthread_rwlock_wrlock(rwlock_); | |
48 DCHECK_EQ(0, result); | |
49 } | |
50 | |
51 ~ScopedWriteLock() { | |
52 int result = pthread_rwlock_unlock(rwlock_); | |
53 DCHECK_EQ(0, result); | |
54 } | |
55 | |
56 protected: | |
57 pthread_rwlock_t* rwlock_; | |
58 private: | |
59 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLock); | |
60 }; | |
61 | |
62 // ScopedReadLock attempts to acquire a read lock in its constructor and then | |
63 // releases it in its destructor. | |
64 class ScopedReadLock { | |
65 public: | |
66 explicit ScopedReadLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) { | |
67 int result = pthread_rwlock_rdlock(rwlock_); | |
68 DCHECK_EQ(0, result); | |
69 } | |
70 | |
71 explicit ScopedReadLock(PThreadRWLock* rwlock) : rwlock_(&rwlock->rwlock_) { | |
72 int result = pthread_rwlock_rdlock(rwlock_); | |
73 DCHECK_EQ(0, result); | |
74 } | |
75 | |
76 ~ScopedReadLock() { | |
77 int result = pthread_rwlock_unlock(rwlock_); | |
78 DCHECK_EQ(0, result); | |
79 } | |
80 protected: | |
81 pthread_rwlock_t* rwlock_; | |
82 private: | |
83 DISALLOW_COPY_AND_ASSIGN(ScopedReadLock); | |
84 }; | |
85 | |
86 template <typename LockType> | 22 template <typename LockType> |
87 class PThreadScopedLock { | 23 class PThreadScopedLock { |
88 public: | 24 public: |
89 explicit inline PThreadScopedLock(LockType* lock) : lock_(lock) { | 25 explicit inline PThreadScopedLock(LockType* lock) : lock_(lock) { |
90 if (lock_) | 26 if (lock_) |
91 lock->Lock(); | 27 lock->Lock(); |
92 } | 28 } |
93 inline ~PThreadScopedLock() { | 29 inline ~PThreadScopedLock() { |
94 Unlock(); | 30 Unlock(); |
95 } | 31 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 91 |
156 #ifndef NDEBUG | 92 #ifndef NDEBUG |
157 pthread_mutexattr_t mutex_attributes_; | 93 pthread_mutexattr_t mutex_attributes_; |
158 bool private_attributes_in_use_; | 94 bool private_attributes_in_use_; |
159 #endif | 95 #endif |
160 | 96 |
161 private: | 97 private: |
162 DISALLOW_COPY_AND_ASSIGN(PThreadMutex); | 98 DISALLOW_COPY_AND_ASSIGN(PThreadMutex); |
163 }; | 99 }; |
164 | 100 |
165 class PThreadMutexAttr { | |
166 public: | |
167 pthread_mutexattr_t attr; | |
168 inline PThreadMutexAttr(int type) { | |
169 pthread_mutexattr_init(&attr); | |
170 pthread_mutexattr_settype(&attr, type); | |
171 } | |
172 inline ~PThreadMutexAttr() { | |
173 pthread_mutexattr_destroy(&attr); | |
174 } | |
175 private: | |
176 DISALLOW_COPY_AND_ASSIGN(PThreadMutexAttr); | |
177 }; | |
178 | |
179 class PThreadRecursiveMutex : public PThreadMutex { | |
180 public: | |
181 inline PThreadRecursiveMutex() : PThreadMutex(recursive_attr()) {} | |
182 private: | |
183 static inline pthread_mutexattr_t* recursive_attr() { | |
184 static PThreadMutexAttr recursive(PTHREAD_MUTEX_RECURSIVE); | |
185 return &recursive.attr; | |
186 } | |
187 DISALLOW_COPY_AND_ASSIGN(PThreadRecursiveMutex); | |
188 }; | |
189 | |
190 | |
191 class PThreadScopedDisabledCancellation { | |
192 public: | |
193 inline PThreadScopedDisabledCancellation() { | |
194 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancel_state_); | |
195 } | |
196 inline ~PThreadScopedDisabledCancellation() { | |
197 pthread_setcancelstate(old_cancel_state_, NULL); | |
198 } | |
199 private: | |
200 int old_cancel_state_; | |
201 | |
202 DISALLOW_COPY_AND_ASSIGN(PThreadScopedDisabledCancellation); | |
203 }; | |
204 | |
205 class PThreadCondVar { | 101 class PThreadCondVar { |
206 public: | 102 public: |
207 inline PThreadCondVar() { | 103 inline PThreadCondVar() { |
208 int result = pthread_cond_init(&condvar_, 0); | 104 int result = pthread_cond_init(&condvar_, 0); |
209 DCHECK_EQ(0, result); | 105 DCHECK_EQ(0, result); |
210 } | 106 } |
211 ~PThreadCondVar() { | 107 ~PThreadCondVar() { |
212 int result = pthread_cond_destroy(&condvar_); | 108 int result = pthread_cond_destroy(&condvar_); |
213 DCHECK_EQ(0, result); | 109 DCHECK_EQ(0, result); |
214 } | 110 } |
215 inline void Signal() { | 111 inline void Signal() { |
216 int result = pthread_cond_signal(&condvar_); | 112 int result = pthread_cond_signal(&condvar_); |
217 DCHECK_EQ(0, result); | 113 DCHECK_EQ(0, result); |
218 } | 114 } |
219 inline void Broadcast() { | 115 inline void Broadcast() { |
220 int result = pthread_cond_broadcast(&condvar_); | 116 int result = pthread_cond_broadcast(&condvar_); |
221 DCHECK_EQ(0, result); | 117 DCHECK_EQ(0, result); |
222 } | 118 } |
223 pthread_cond_t condvar_; | 119 pthread_cond_t condvar_; |
224 | 120 |
225 private: | 121 private: |
226 DISALLOW_COPY_AND_ASSIGN(PThreadCondVar); | 122 DISALLOW_COPY_AND_ASSIGN(PThreadCondVar); |
227 }; | 123 }; |
228 | 124 |
229 template <typename ValueType> | |
230 class PThreadThreadVar { | |
231 public: | |
232 PThreadThreadVar(void (*destructor)(void* payload)) { | |
233 int result = pthread_key_create(&thread_key_, destructor); | |
234 DCHECK_EQ(0, result); | |
235 } | |
236 ~PThreadThreadVar() { | |
237 int result = pthread_key_delete(thread_key_); | |
238 DCHECK_EQ(0, result); | |
239 } | |
240 void SetValue(ValueType value) { | |
241 int result = pthread_setspecific(thread_key_, static_cast<void*>(value)); | |
242 DCHECK_EQ(0, result); | |
243 } | |
244 ValueType GetValue() { | |
245 return static_cast<ValueType>(pthread_getspecific(thread_key_)); | |
246 } | |
247 private: | |
248 pthread_key_t thread_key_; | |
249 DISALLOW_COPY_AND_ASSIGN(PThreadThreadVar); | |
250 }; | |
251 | |
252 // Returns the absolute time ms milliseconds from now. Useful for passing | 125 // Returns the absolute time ms milliseconds from now. Useful for passing |
253 // result to pthread_cond_timedwait(). | 126 // result to pthread_cond_timedwait(). |
254 struct timespec GetPThreadAbsoluteTime(uint32 ms_from_now); | 127 struct timespec GetPThreadAbsoluteTime(uint32 ms_from_now); |
255 | 128 |
256 // Assign a descriptive label to the current thread. This is useful to see | 129 // Assign a descriptive label to the current thread. This is useful to see |
257 // in a GUI debugger, but may not be implementable on all platforms. | 130 // in a GUI debugger, but may not be implementable on all platforms. |
258 void NameCurrentThreadForDebugging(char* name); | 131 void NameCurrentThreadForDebugging(char* name); |
259 | 132 |
260 #endif // CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ | 133 #endif // CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ |
OLD | NEW |