• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(_WIN32)
24  # include <pthread.h>
25  #endif
26  
27  #include <utils/Errors.h>
28  #include <utils/ThreadDefs.h>
29  
30  // ---------------------------------------------------------------------------
31  namespace android {
32  // ---------------------------------------------------------------------------
33  
34  #if !defined(_WIN32)
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   */
42  class RWLock {
43  public:
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:
AutoRLock(RWLock & rwlock)62          inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
~AutoRLock()63          inline ~AutoRLock() { mLock.unlock(); }
64      private:
65          RWLock& mLock;
66      };
67  
68      class AutoWLock {
69      public:
AutoWLock(RWLock & rwlock)70          inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
~AutoWLock()71          inline ~AutoWLock() { mLock.unlock(); }
72      private:
73          RWLock& mLock;
74      };
75  
76  private:
77      // A RWLock cannot be copied
78                  RWLock(const RWLock&);
79     RWLock&      operator = (const RWLock&);
80  
81     pthread_rwlock_t mRWLock;
82  };
83  
RWLock()84  inline RWLock::RWLock() {
85      pthread_rwlock_init(&mRWLock, NULL);
86  }
RWLock(const char * name)87  inline RWLock::RWLock(__attribute__((unused)) const char* name) {
88      pthread_rwlock_init(&mRWLock, NULL);
89  }
RWLock(int type,const char * name)90  inline RWLock::RWLock(int type, __attribute__((unused)) 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  }
~RWLock()101  inline RWLock::~RWLock() {
102      pthread_rwlock_destroy(&mRWLock);
103  }
readLock()104  inline status_t RWLock::readLock() {
105      return -pthread_rwlock_rdlock(&mRWLock);
106  }
tryReadLock()107  inline status_t RWLock::tryReadLock() {
108      return -pthread_rwlock_tryrdlock(&mRWLock);
109  }
writeLock()110  inline status_t RWLock::writeLock() {
111      return -pthread_rwlock_wrlock(&mRWLock);
112  }
tryWriteLock()113  inline status_t RWLock::tryWriteLock() {
114      return -pthread_rwlock_trywrlock(&mRWLock);
115  }
unlock()116  inline void RWLock::unlock() {
117      pthread_rwlock_unlock(&mRWLock);
118  }
119  
120  #endif // !defined(_WIN32)
121  
122  // ---------------------------------------------------------------------------
123  }; // namespace android
124  // ---------------------------------------------------------------------------
125  
126  #endif // _LIBS_UTILS_RWLOCK_H
127