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// --------------------------------------------------------------------------- 31namespace android { 32// --------------------------------------------------------------------------- 33 34class 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 */ 42class Mutex { 43public: 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 72private: 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 91inline Mutex::Mutex() { 92 pthread_mutex_init(&mMutex, NULL); 93} 94inline Mutex::Mutex(const char* name) { 95 pthread_mutex_init(&mMutex, NULL); 96} 97inline Mutex::Mutex(int type, 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} 108inline Mutex::~Mutex() { 109 pthread_mutex_destroy(&mMutex); 110} 111inline status_t Mutex::lock() { 112 return -pthread_mutex_lock(&mMutex); 113} 114inline void Mutex::unlock() { 115 pthread_mutex_unlock(&mMutex); 116} 117inline 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 131typedef Mutex::Autolock AutoMutex; 132 133// --------------------------------------------------------------------------- 134}; // namespace android 135// --------------------------------------------------------------------------- 136 137#endif // _LIBS_UTILS_MUTEX_H 138