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