| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef SkMutex_pthread_DEFINED | 8 #ifndef SkMutex_pthread_DEFINED |
| 9 #define SkMutex_pthread_DEFINED | 9 #define SkMutex_pthread_DEFINED |
| 10 | 10 |
| 11 /** Posix pthread_mutex based mutex. */ | 11 /** Posix pthread_mutex based mutex. */ |
| 12 | 12 |
| 13 #include <errno.h> | 13 #include <errno.h> |
| 14 #include <pthread.h> | 14 #include <pthread.h> |
| 15 | 15 |
| 16 // This isn't technically portable, but on Linux and Android pthread_t is some s
ort of int, and |
| 17 // on Darwin it's a pointer. So assuming pthread_self() never returns 0, it wor
ks as a sentinel. |
| 18 SkDEBUGCODE(static const pthread_t kNoOwner = 0;) |
| 19 |
| 16 // A SkBaseMutex is a POD structure that can be directly initialized | 20 // A SkBaseMutex is a POD structure that can be directly initialized |
| 17 // at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the | 21 // at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the |
| 18 // generation of a static initializer in the final machine code (and | 22 // generation of a static initializer in the final machine code (and |
| 19 // a corresponding static finalizer). | 23 // a corresponding static finalizer). |
| 20 struct SkBaseMutex { | 24 struct SkBaseMutex { |
| 21 void acquire() { | 25 void acquire() { |
| 22 SkASSERT(fOwner != pthread_self()); // SkMutex is not re-entrant | 26 SkASSERT(0 == pthread_equal(fOwner, pthread_self())); // SkMutex is not
re-entrant |
| 23 pthread_mutex_lock(&fMutex); | 27 pthread_mutex_lock(&fMutex); |
| 24 SkDEBUGCODE(fOwner = pthread_self();) | 28 SkDEBUGCODE(fOwner = pthread_self();) |
| 25 } | 29 } |
| 26 void release() { | 30 void release() { |
| 27 this->assertHeld(); | 31 this->assertHeld(); |
| 28 SkDEBUGCODE(fOwner = 0;) | 32 SkDEBUGCODE(fOwner = kNoOwner;) |
| 29 pthread_mutex_unlock(&fMutex); | 33 pthread_mutex_unlock(&fMutex); |
| 30 } | 34 } |
| 31 void assertHeld() { | 35 void assertHeld() { |
| 32 SkASSERT(pthread_self() == fOwner); | 36 SkASSERT(0 != pthread_equal(fOwner, pthread_self())); |
| 33 } | 37 } |
| 34 | 38 |
| 35 pthread_mutex_t fMutex; | 39 pthread_mutex_t fMutex; |
| 36 SkDEBUGCODE(pthread_t fOwner;) | 40 SkDEBUGCODE(pthread_t fOwner;) |
| 37 }; | 41 }; |
| 38 | 42 |
| 39 // A normal mutex that requires to be initialized through normal C++ constructio
n, | 43 // A normal mutex that requires to be initialized through normal C++ constructio
n, |
| 40 // i.e. when it's a member of another class, or allocated on the heap. | 44 // i.e. when it's a member of another class, or allocated on the heap. |
| 41 class SkMutex : public SkBaseMutex { | 45 class SkMutex : public SkBaseMutex { |
| 42 public: | 46 public: |
| 43 SkMutex() { | 47 SkMutex() { |
| 44 SkDEBUGCODE(int status = )pthread_mutex_init(&fMutex, NULL); | 48 SkDEBUGCODE(int status = )pthread_mutex_init(&fMutex, NULL); |
| 45 SkDEBUGCODE( | 49 SkDEBUGCODE( |
| 46 if (status != 0) { | 50 if (status != 0) { |
| 47 print_pthread_error(status); | 51 print_pthread_error(status); |
| 48 SkASSERT(0 == status); | 52 SkASSERT(0 == status); |
| 49 } | 53 } |
| 54 fOwner = kNoOwner; |
| 50 ) | 55 ) |
| 51 } | 56 } |
| 52 | 57 |
| 53 ~SkMutex() { | 58 ~SkMutex() { |
| 54 SkDEBUGCODE(int status = )pthread_mutex_destroy(&fMutex); | 59 SkDEBUGCODE(int status = )pthread_mutex_destroy(&fMutex); |
| 55 SkDEBUGCODE( | 60 SkDEBUGCODE( |
| 56 if (status != 0) { | 61 if (status != 0) { |
| 57 print_pthread_error(status); | 62 print_pthread_error(status); |
| 58 SkASSERT(0 == status); | 63 SkASSERT(0 == status); |
| 59 } | 64 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 83 | 88 |
| 84 #define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) } | 89 #define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) } |
| 85 | 90 |
| 86 // Using POD-style initialization prevents the generation of a static initialize
r. | 91 // Using POD-style initialization prevents the generation of a static initialize
r. |
| 87 #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_IN
IT | 92 #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_IN
IT |
| 88 | 93 |
| 89 // Special case used when the static mutex must be available globally. | 94 // Special case used when the static mutex must be available globally. |
| 90 #define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT | 95 #define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT |
| 91 | 96 |
| 92 #endif | 97 #endif |
| OLD | NEW |