12bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 22bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Copyright (C) 2007 The Android Open Source Project 32bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 42bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 52bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * you may not use this file except in compliance with the License. 62bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * You may obtain a copy of the License at 72bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 82bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 92bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Unless required by applicable law or agreed to in writing, software 112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * See the License for the specific language governing permissions and 142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * limitations under the License. 152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#ifndef _LIBS_UTILS_MUTEX_H 182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#define _LIBS_UTILS_MUTEX_H 192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <stdint.h> 212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <sys/types.h> 222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <time.h> 232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian# include <pthread.h> 262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Errors.h> 292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopiannamespace android { 322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianclass Condition; 352bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 362bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 372bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Simple mutex class. The implementation is system-dependent. 382bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 392bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * The mutex must be unlocked by the thread that locked it. They are not 402bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * recursive, i.e. the same thread can't lock it multiple times. 412bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 422bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianclass Mutex { 432bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianpublic: 442bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian enum { 452bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian PRIVATE = 0, 462bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian SHARED = 1 472bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian }; 482bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 492bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex(); 502bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex(const char* name); 512bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex(int type, const char* name = NULL); 522bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ~Mutex(); 532bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 542bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // lock or unlock the mutex 552bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t lock(); 562bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void unlock(); 572bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 582bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // lock if possible; returns 0 on success, error otherwise 592bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t tryLock(); 602bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 612bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Manages the mutex automatically. It'll be locked when Autolock is 622bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // constructed and released when Autolock goes out of scope. 632bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian class Autolock { 642bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian public: 652bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 662bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 672bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian inline ~Autolock() { mLock.unlock(); } 682bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian private: 692bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex& mLock; 702bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian }; 712bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 722bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate: 732bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian friend class Condition; 742bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 752bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // A mutex cannot be copied 762bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex(const Mutex&); 772bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Mutex& operator = (const Mutex&); 782bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 792bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 802bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_t mMutex; 812bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else 822bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void _init(); 832bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void* mState; 842bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 852bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; 862bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 872bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 882bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 892bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 902bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 912bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Mutex::Mutex() { 922bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_init(&mMutex, NULL); 932bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 94a27c1e08396aa2969511dad1f661d10c2b835ac1Igor Murashkininline Mutex::Mutex(__attribute__((unused)) const char* name) { 952bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_init(&mMutex, NULL); 962bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 97a27c1e08396aa2969511dad1f661d10c2b835ac1Igor Murashkininline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { 982bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian if (type == SHARED) { 992bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutexattr_t attr; 1002bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutexattr_init(&attr); 1012bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 1022bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_init(&mMutex, &attr); 1032bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutexattr_destroy(&attr); 1042bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } else { 1052bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_init(&mMutex, NULL); 1062bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } 1072bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1082bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Mutex::~Mutex() { 1092bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_destroy(&mMutex); 1102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Mutex::lock() { 1122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_mutex_lock(&mMutex); 1132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void Mutex::unlock() { 1152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_mutex_unlock(&mMutex); 1162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Mutex::tryLock() { 1182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_mutex_trylock(&mMutex); 1192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREADS 1222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 1262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Automatic mutex. Declare one of these at the top of a function. 1272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * When the function returns, it will go out of scope, and release the 1282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * mutex. 1292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 1302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopiantypedef Mutex::Autolock AutoMutex; 1322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; // namespace android 1352bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1362bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1372bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // _LIBS_UTILS_MUTEX_H 138