1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBS_UTILS_MUTEX_H 18 #define _LIBS_UTILS_MUTEX_H 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 #include <time.h> 23 24 #if defined(HAVE_PTHREADS) 25 # include <pthread.h> 26 #endif 27 28 #include <utils/Errors.h> 29 30 // --------------------------------------------------------------------------- 31 namespace android { 32 // --------------------------------------------------------------------------- 33 34 class Condition; 35 36 /* 37 * Simple mutex class. The implementation is system-dependent. 38 * 39 * The mutex must be unlocked by the thread that locked it. They are not 40 * recursive, i.e. the same thread can't lock it multiple times. 41 */ 42 class Mutex { 43 public: 44 enum { 45 PRIVATE = 0, 46 SHARED = 1 47 }; 48 49 Mutex(); 50 Mutex(const char* name); 51 Mutex(int type, const char* name = NULL); 52 ~Mutex(); 53 54 // lock or unlock the mutex 55 status_t lock(); 56 void unlock(); 57 58 // lock if possible; returns 0 on success, error otherwise 59 status_t tryLock(); 60 61 // Manages the mutex automatically. It'll be locked when Autolock is 62 // constructed and released when Autolock goes out of scope. 63 class Autolock { 64 public: 65 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 66 inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 67 inline ~Autolock() { mLock.unlock(); } 68 private: 69 Mutex& mLock; 70 }; 71 72 private: 73 friend class Condition; 74 75 // A mutex cannot be copied 76 Mutex(const Mutex&); 77 Mutex& operator = (const Mutex&); 78 79 #if defined(HAVE_PTHREADS) 80 pthread_mutex_t mMutex; 81 #else 82 void _init(); 83 void* mState; 84 #endif 85 }; 86 87 // --------------------------------------------------------------------------- 88 89 #if defined(HAVE_PTHREADS) 90 91 inline Mutex::Mutex() { 92 pthread_mutex_init(&mMutex, NULL); 93 } 94 inline Mutex::Mutex(__attribute__((unused)) const char* name) { 95 pthread_mutex_init(&mMutex, NULL); 96 } 97 inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { 98 if (type == SHARED) { 99 pthread_mutexattr_t attr; 100 pthread_mutexattr_init(&attr); 101 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 102 pthread_mutex_init(&mMutex, &attr); 103 pthread_mutexattr_destroy(&attr); 104 } else { 105 pthread_mutex_init(&mMutex, NULL); 106 } 107 } 108 inline Mutex::~Mutex() { 109 pthread_mutex_destroy(&mMutex); 110 } 111 inline status_t Mutex::lock() { 112 return -pthread_mutex_lock(&mMutex); 113 } 114 inline void Mutex::unlock() { 115 pthread_mutex_unlock(&mMutex); 116 } 117 inline status_t Mutex::tryLock() { 118 return -pthread_mutex_trylock(&mMutex); 119 } 120 121 #endif // HAVE_PTHREADS 122 123 // --------------------------------------------------------------------------- 124 125 /* 126 * Automatic mutex. Declare one of these at the top of a function. 127 * When the function returns, it will go out of scope, and release the 128 * mutex. 129 */ 130 131 typedef Mutex::Autolock AutoMutex; 132 133 // --------------------------------------------------------------------------- 134 }; // namespace android 135 // --------------------------------------------------------------------------- 136 137 #endif // _LIBS_UTILS_MUTEX_H 138