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_RWLOCK_H
182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#define _LIBS_UTILS_RWLOCK_H
192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <stdint.h>
212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <sys/types.h>
222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS)
242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian# include <pthread.h>
252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif
262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Errors.h>
282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/ThreadDefs.h>
292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// ---------------------------------------------------------------------------
312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopiannamespace android {
322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// ---------------------------------------------------------------------------
332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS)
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 RWLock {
432bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianpublic:
442bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    enum {
452bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        PRIVATE = 0,
462bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        SHARED = 1
472bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    };
482bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
492bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian                RWLock();
502bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian                RWLock(const char* name);
512bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian                RWLock(int type, const char* name = NULL);
522bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian                ~RWLock();
532bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
542bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    status_t    readLock();
552bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    status_t    tryReadLock();
562bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    status_t    writeLock();
572bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    status_t    tryWriteLock();
582bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    void        unlock();
592bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
602bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    class AutoRLock {
612bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    public:
622bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
632bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        inline ~AutoRLock() { mLock.unlock(); }
642bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    private:
652bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        RWLock& mLock;
662bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    };
672bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
682bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    class AutoWLock {
692bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    public:
702bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
712bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        inline ~AutoWLock() { mLock.unlock(); }
722bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    private:
732bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        RWLock& mLock;
742bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    };
752bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
762bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate:
772bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    // A RWLock cannot be copied
782bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian                RWLock(const RWLock&);
792bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian   RWLock&      operator = (const RWLock&);
802bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
812bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian   pthread_rwlock_t mRWLock;
822bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian};
832bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
842bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline RWLock::RWLock() {
852bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    pthread_rwlock_init(&mRWLock, NULL);
862bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
87a27c1e08396aa2969511dad1f661d10c2b835ac1Igor Murashkininline RWLock::RWLock(__attribute__((unused)) const char* name) {
882bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    pthread_rwlock_init(&mRWLock, NULL);
892bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
90a27c1e08396aa2969511dad1f661d10c2b835ac1Igor Murashkininline RWLock::RWLock(int type, __attribute__((unused)) const char* name) {
912bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    if (type == SHARED) {
922bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlockattr_t attr;
932bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlockattr_init(&attr);
942bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
952bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlock_init(&mRWLock, &attr);
962bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlockattr_destroy(&attr);
972bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    } else {
982bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian        pthread_rwlock_init(&mRWLock, NULL);
992bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    }
1002bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1012bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline RWLock::~RWLock() {
1022bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    pthread_rwlock_destroy(&mRWLock);
1032bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1042bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t RWLock::readLock() {
1052bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    return -pthread_rwlock_rdlock(&mRWLock);
1062bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1072bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t RWLock::tryReadLock() {
1082bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    return -pthread_rwlock_tryrdlock(&mRWLock);
1092bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t RWLock::writeLock() {
1112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    return -pthread_rwlock_wrlock(&mRWLock);
1122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t RWLock::tryWriteLock() {
1142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    return -pthread_rwlock_trywrlock(&mRWLock);
1152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void RWLock::unlock() {
1172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian    pthread_rwlock_unlock(&mRWLock);
1182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}
1192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
1202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREADS
1212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
1222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// ---------------------------------------------------------------------------
1232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; // namespace android
1242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// ---------------------------------------------------------------------------
1252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian
1262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // _LIBS_UTILS_RWLOCK_H
127