blob: de6fb394ad9c4d3a465574c396bad1065047256b [file] [log] [blame]
Mathias Agopianf91bb052012-02-25 23:02:14 -08001/*
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_MUTEX_H
18#define _LIBS_UTILS_MUTEX_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <time.h>
23
24#if defined(HAVE_PTHREADS)
25# include <pthread.h>
26#endif
27
28#include <utils/Errors.h>
29
30// ---------------------------------------------------------------------------
31namespace android {
32// ---------------------------------------------------------------------------
33
34class Condition;
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 Mutex {
43public:
44 enum {
45 PRIVATE = 0,
46 SHARED = 1
47 };
48
49 Mutex();
50 Mutex(const char* name);
51 Mutex(int type, const char* name = NULL);
52 ~Mutex();
53
54 // lock or unlock the mutex
55 status_t lock();
56 void unlock();
57
58 // lock if possible; returns 0 on success, error otherwise
59 status_t tryLock();
60
61 // Manages the mutex automatically. It'll be locked when Autolock is
62 // constructed and released when Autolock goes out of scope.
63 class Autolock {
64 public:
65 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
66 inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
67 inline ~Autolock() { mLock.unlock(); }
68 private:
69 Mutex& mLock;
70 };
71
72private:
73 friend class Condition;
74
75 // A mutex cannot be copied
76 Mutex(const Mutex&);
77 Mutex& operator = (const Mutex&);
78
79#if defined(HAVE_PTHREADS)
80 pthread_mutex_t mMutex;
81#else
82 void _init();
83 void* mState;
84#endif
85};
86
87// ---------------------------------------------------------------------------
88
89#if defined(HAVE_PTHREADS)
90
91inline Mutex::Mutex() {
92 pthread_mutex_init(&mMutex, NULL);
93}
94inline Mutex::Mutex(const char* name) {
95 pthread_mutex_init(&mMutex, NULL);
96}
97inline Mutex::Mutex(int type, const char* name) {
98 if (type == SHARED) {
99 pthread_mutexattr_t attr;
100 pthread_mutexattr_init(&attr);
101 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
102 pthread_mutex_init(&mMutex, &attr);
103 pthread_mutexattr_destroy(&attr);
104 } else {
105 pthread_mutex_init(&mMutex, NULL);
106 }
107}
108inline Mutex::~Mutex() {
109 pthread_mutex_destroy(&mMutex);
110}
111inline status_t Mutex::lock() {
112 return -pthread_mutex_lock(&mMutex);
113}
114inline void Mutex::unlock() {
115 pthread_mutex_unlock(&mMutex);
116}
117inline status_t Mutex::tryLock() {
118 return -pthread_mutex_trylock(&mMutex);
119}
120
121#endif // HAVE_PTHREADS
122
123// ---------------------------------------------------------------------------
124
125/*
126 * Automatic mutex. Declare one of these at the top of a function.
127 * When the function returns, it will go out of scope, and release the
128 * mutex.
129 */
130
131typedef Mutex::Autolock AutoMutex;
132
133// ---------------------------------------------------------------------------
134}; // namespace android
135// ---------------------------------------------------------------------------
136
137#endif // _LIBS_UTILS_MUTEX_H