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(_WIN32) 25# include <pthread.h> 26#endif 27 28#include <utils/Errors.h> 29#include <utils/Timers.h> 30 31// --------------------------------------------------------------------------- 32namespace android { 33// --------------------------------------------------------------------------- 34 35class Condition; 36 37/* 38 * Simple mutex class. The implementation is system-dependent. 39 * 40 * The mutex must be unlocked by the thread that locked it. They are not 41 * recursive, i.e. the same thread can't lock it multiple times. 42 */ 43class Mutex { 44public: 45 enum { 46 PRIVATE = 0, 47 SHARED = 1 48 }; 49 50 Mutex(); 51 Mutex(const char* name); 52 Mutex(int type, const char* name = NULL); 53 ~Mutex(); 54 55 // lock or unlock the mutex 56 status_t lock(); 57 void unlock(); 58 59 // lock if possible; returns 0 on success, error otherwise 60 status_t tryLock(); 61 62#if HAVE_ANDROID_OS 63 // lock the mutex, but don't wait longer than timeoutMilliseconds. 64 // Returns 0 on success, TIMED_OUT for failure due to timeout expiration. 65 // 66 // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep 67 // capabilities consistent across host OSes, this method is only available 68 // when building Android binaries. 69 status_t timedLock(nsecs_t timeoutMilliseconds); 70#endif 71 72 // Manages the mutex automatically. It'll be locked when Autolock is 73 // constructed and released when Autolock goes out of scope. 74 class Autolock { 75 public: 76 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 77 inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 78 inline ~Autolock() { mLock.unlock(); } 79 private: 80 Mutex& mLock; 81 }; 82 83private: 84 friend class Condition; 85 86 // A mutex cannot be copied 87 Mutex(const Mutex&); 88 Mutex& operator = (const Mutex&); 89 90#if !defined(_WIN32) 91 pthread_mutex_t mMutex; 92#else 93 void _init(); 94 void* mState; 95#endif 96}; 97 98// --------------------------------------------------------------------------- 99 100#if !defined(_WIN32) 101 102inline Mutex::Mutex() { 103 pthread_mutex_init(&mMutex, NULL); 104} 105inline Mutex::Mutex(__attribute__((unused)) const char* name) { 106 pthread_mutex_init(&mMutex, NULL); 107} 108inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { 109 if (type == SHARED) { 110 pthread_mutexattr_t attr; 111 pthread_mutexattr_init(&attr); 112 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 113 pthread_mutex_init(&mMutex, &attr); 114 pthread_mutexattr_destroy(&attr); 115 } else { 116 pthread_mutex_init(&mMutex, NULL); 117 } 118} 119inline Mutex::~Mutex() { 120 pthread_mutex_destroy(&mMutex); 121} 122inline status_t Mutex::lock() { 123 return -pthread_mutex_lock(&mMutex); 124} 125inline void Mutex::unlock() { 126 pthread_mutex_unlock(&mMutex); 127} 128inline status_t Mutex::tryLock() { 129 return -pthread_mutex_trylock(&mMutex); 130} 131#if HAVE_ANDROID_OS 132inline status_t Mutex::timedLock(nsecs_t timeoutNs) { 133 const struct timespec ts = { 134 /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000), 135 /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000), 136 }; 137 return -pthread_mutex_timedlock(&mMutex, &ts); 138} 139#endif 140 141#endif // !defined(_WIN32) 142 143// --------------------------------------------------------------------------- 144 145/* 146 * Automatic mutex. Declare one of these at the top of a function. 147 * When the function returns, it will go out of scope, and release the 148 * mutex. 149 */ 150 151typedef Mutex::Autolock AutoMutex; 152 153// --------------------------------------------------------------------------- 154}; // namespace android 155// --------------------------------------------------------------------------- 156 157#endif // _LIBS_UTILS_MUTEX_H 158