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