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_RWLOCK_H 18#define _LIBS_UTILS_RWLOCK_H 19 20#include <stdint.h> 21#include <sys/types.h> 22 23#if defined(HAVE_PTHREADS) 24# include <pthread.h> 25#endif 26 27#include <utils/Errors.h> 28#include <utils/ThreadDefs.h> 29 30// --------------------------------------------------------------------------- 31namespace android { 32// --------------------------------------------------------------------------- 33 34#if defined(HAVE_PTHREADS) 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 RWLock { 43public: 44 enum { 45 PRIVATE = 0, 46 SHARED = 1 47 }; 48 49 RWLock(); 50 RWLock(const char* name); 51 RWLock(int type, const char* name = NULL); 52 ~RWLock(); 53 54 status_t readLock(); 55 status_t tryReadLock(); 56 status_t writeLock(); 57 status_t tryWriteLock(); 58 void unlock(); 59 60 class AutoRLock { 61 public: 62 inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } 63 inline ~AutoRLock() { mLock.unlock(); } 64 private: 65 RWLock& mLock; 66 }; 67 68 class AutoWLock { 69 public: 70 inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } 71 inline ~AutoWLock() { mLock.unlock(); } 72 private: 73 RWLock& mLock; 74 }; 75 76private: 77 // A RWLock cannot be copied 78 RWLock(const RWLock&); 79 RWLock& operator = (const RWLock&); 80 81 pthread_rwlock_t mRWLock; 82}; 83 84inline RWLock::RWLock() { 85 pthread_rwlock_init(&mRWLock, NULL); 86} 87inline RWLock::RWLock(const char* name) { 88 pthread_rwlock_init(&mRWLock, NULL); 89} 90inline RWLock::RWLock(int type, const char* name) { 91 if (type == SHARED) { 92 pthread_rwlockattr_t attr; 93 pthread_rwlockattr_init(&attr); 94 pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 95 pthread_rwlock_init(&mRWLock, &attr); 96 pthread_rwlockattr_destroy(&attr); 97 } else { 98 pthread_rwlock_init(&mRWLock, NULL); 99 } 100} 101inline RWLock::~RWLock() { 102 pthread_rwlock_destroy(&mRWLock); 103} 104inline status_t RWLock::readLock() { 105 return -pthread_rwlock_rdlock(&mRWLock); 106} 107inline status_t RWLock::tryReadLock() { 108 return -pthread_rwlock_tryrdlock(&mRWLock); 109} 110inline status_t RWLock::writeLock() { 111 return -pthread_rwlock_wrlock(&mRWLock); 112} 113inline status_t RWLock::tryWriteLock() { 114 return -pthread_rwlock_trywrlock(&mRWLock); 115} 116inline void RWLock::unlock() { 117 pthread_rwlock_unlock(&mRWLock); 118} 119 120#endif // HAVE_PTHREADS 121 122// --------------------------------------------------------------------------- 123}; // namespace android 124// --------------------------------------------------------------------------- 125 126#endif // _LIBS_UTILS_RWLOCK_H 127