SkMutex_pthread.h revision d9947f605a335363b0a0541d6d8cb7a7113ed788
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef SkMutex_pthread_DEFINED 9#define SkMutex_pthread_DEFINED 10 11/** Posix pthread_mutex based mutex. */ 12 13#ifdef SK_DEBUG_PTHREAD_MUTEX 14#include "SkTypes.h" 15#define SkDEBUGCODE_PTHREAD_MUTEX(code) code 16#else 17#define SkDEBUGCODE_PTHREAD_MUTEX(code) 18#ifndef SkDebugf 19 void SkDebugf(const char format[], ...); 20#endif 21#endif 22 23#include <errno.h> 24#include <pthread.h> 25 26// A SkBaseMutex is a POD structure that can be directly initialized 27// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the 28// generation of a static initializer in the final machine code (and 29// a corresponding static finalizer). 30struct SkBaseMutex { 31 void acquire() { pthread_mutex_lock(&fMutex); } 32 void release() { pthread_mutex_unlock(&fMutex); } 33 pthread_mutex_t fMutex; 34}; 35 36// A normal mutex that requires to be initialized through normal C++ construction, 37// i.e. when it's a member of another class, or allocated on the heap. 38class SkMutex : public SkBaseMutex { 39public: 40 SkMutex() { 41 SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_init(&fMutex, NULL); 42 SkDEBUGCODE_PTHREAD_MUTEX( 43 if (status != 0) { 44 print_pthread_error(status); 45 SkASSERT(0 == status); 46 } 47 ) 48 } 49 50 ~SkMutex() { 51 SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_destroy(&fMutex); 52 SkDEBUGCODE_PTHREAD_MUTEX( 53 if (status != 0) { 54 print_pthread_error(status); 55 SkASSERT(0 == status); 56 } 57 ) 58 } 59 60private: 61 SkMutex(const SkMutex&); 62 SkMutex& operator=(const SkMutex&); 63 64 static void print_pthread_error(int status) { 65 switch (status) { 66 case 0: // success 67 break; 68 case EINVAL: 69 SkDebugf("pthread error [%d] EINVAL\n", status); 70 break; 71 case EBUSY: 72 SkDebugf("pthread error [%d] EBUSY\n", status); 73 break; 74 default: 75 SkDebugf("pthread error [%d] unknown\n", status); 76 break; 77 } 78 } 79}; 80 81// Using POD-style initialization prevents the generation of a static initializer. 82#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } 83 84// Special case used when the static mutex must be available globally. 85#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } 86 87#endif 88