00001 #ifndef _sys_posix_Mutex_h
00002 #define _sys_posix_Mutex_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "check.h"
00023
00024 #include <pthread.h>
00025 #include <boost/noncopyable.hpp>
00026
00027 namespace qpid {
00028 namespace sys {
00029
00030 class Condition;
00031
00035 class Mutex : private boost::noncopyable {
00036 friend class Condition;
00037
00038 public:
00039 typedef ::qpid::sys::ScopedLock<Mutex> ScopedLock;
00040 typedef ::qpid::sys::ScopedUnlock<Mutex> ScopedUnlock;
00041
00042 inline Mutex();
00043 inline ~Mutex();
00044 inline void lock();
00045 inline void unlock();
00046 inline bool trylock();
00047
00048
00049 protected:
00050 pthread_mutex_t mutex;
00051 };
00052
00056 class RWlock : private boost::noncopyable {
00057 friend class Condition;
00058
00059 public:
00060 typedef ::qpid::sys::ScopedRlock<RWlock> ScopedRlock;
00061 typedef ::qpid::sys::ScopedWlock<RWlock> ScopedWlock;
00062
00063 inline RWlock();
00064 inline ~RWlock();
00065 inline void wlock();
00066 inline void rlock();
00067 inline void unlock();
00068 inline void trywlock();
00069 inline void tryrlock();
00070
00071 protected:
00072 pthread_rwlock_t rwlock;
00073 };
00074
00075
00080 namespace {
00081 pthread_once_t onceControl = PTHREAD_ONCE_INIT;
00082 pthread_rwlockattr_t rwlockattr;
00083 pthread_mutexattr_t mutexattr;
00084
00085 void initMutexattr() {
00086 pthread_mutexattr_init(&mutexattr);
00087 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
00088 }
00089
00090 void initRWlockattr() {
00091 pthread_rwlockattr_init(&rwlockattr);
00092 }
00093
00094 struct RecursiveMutexattr {
00095 RecursiveMutexattr() {
00096 pthread_once(&onceControl, initMutexattr);
00097 }
00098
00099 operator const pthread_mutexattr_t*() const {
00100 return &mutexattr;
00101 }
00102 };
00103 struct RecursiveRWlockattr {
00104 RecursiveRWlockattr() {
00105 pthread_once(&onceControl, initRWlockattr);
00106 }
00107
00108 operator const pthread_rwlockattr_t*() const {
00109 return &rwlockattr;
00110 }
00111 };
00112
00113 RecursiveMutexattr recursiveMutexattr;
00114 RecursiveRWlockattr recursiveRWlockattr;
00115
00116
00117
00118 }
00119
00124 struct PODMutex
00125 {
00126 typedef ::qpid::sys::ScopedLock<PODMutex> ScopedLock;
00127
00128 inline void lock();
00129 inline void unlock();
00130 inline bool trylock();
00131
00132
00133 pthread_mutex_t mutex;
00134 };
00135
00136 #define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
00137
00138 void PODMutex::lock() {
00139 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_lock(&mutex));
00140 }
00141
00142 void PODMutex::unlock() {
00143 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_unlock(&mutex));
00144 }
00145
00146 bool PODMutex::trylock() {
00147 return pthread_mutex_trylock(&mutex) == 0;
00148 }
00149
00150 Mutex::Mutex() {
00151 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_init(&mutex, recursiveMutexattr));
00152 }
00153
00154 Mutex::~Mutex(){
00155 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_destroy(&mutex));
00156 }
00157
00158 void Mutex::lock() {
00159 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_lock(&mutex));
00160 }
00161
00162 void Mutex::unlock() {
00163 QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_unlock(&mutex));
00164 }
00165
00166 bool Mutex::trylock() {
00167 return pthread_mutex_trylock(&mutex) == 0;
00168 }
00169
00170
00171 RWlock::RWlock() {
00172 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_init(&rwlock, recursiveRWlockattr));
00173 }
00174
00175 RWlock::~RWlock(){
00176 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_destroy(&rwlock));
00177 }
00178
00179 void RWlock::wlock() {
00180 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_wrlock(&rwlock));
00181 }
00182
00183 void RWlock::rlock() {
00184 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_rdlock(&rwlock));
00185 }
00186
00187 void RWlock::unlock() {
00188 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_unlock(&rwlock));
00189 }
00190
00191 void RWlock::trywlock() {
00192 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_trywrlock(&rwlock));
00193 }
00194
00195 void RWlock::tryrlock() {
00196 QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_tryrdlock(&rwlock));
00197 }
00198
00199
00200 }}
00201 #endif