00001 #ifndef _sys_Mutex_h
00002 #define _sys_Mutex_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef USE_APR
00023 #include <apr_thread_mutex.h>
00024 #include "apr/APRBase.h"
00025 #include "apr/APRPool.h"
00026 #else
00027 #include <pthread.h>
00028 #include "posix/check.h"
00029 #endif
00030 #include <boost/noncopyable.hpp>
00031
00032 namespace qpid {
00033 namespace sys {
00034
00035 class Condition;
00036
00041 template <class L>
00042 class ScopedLock
00043 {
00044 public:
00045 ScopedLock(L& l) : mutex(l) { l.lock(); }
00046 ~ScopedLock() { mutex.unlock(); }
00047 private:
00048 L& mutex;
00049 };
00050
00051 template <class L>
00052 class ScopedUnlock
00053 {
00054 public:
00055 ScopedUnlock(L& l) : mutex(l) { l.unlock(); }
00056 ~ScopedUnlock() { mutex.lock(); }
00057 private:
00058 L& mutex;
00059 };
00060
00064 class Mutex : private boost::noncopyable {
00065 public:
00066 typedef ScopedLock<Mutex> ScopedLock;
00067 typedef ScopedUnlock<Mutex> ScopedUnlock;
00068
00069 inline Mutex();
00070 inline ~Mutex();
00071 inline void lock();
00072 inline void unlock();
00073 inline void trylock();
00074
00075 protected:
00076 #ifdef USE_APR
00077 apr_thread_mutex_t* mutex;
00078 #else
00079 pthread_mutex_t mutex;
00080 #endif
00081 friend class Condition;
00082 };
00083
00084 #ifdef USE_APR
00085
00086
00087 Mutex::Mutex() {
00088 CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get()));
00089 }
00090
00091 Mutex::~Mutex(){
00092 CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
00093 }
00094
00095 void Mutex::lock() {
00096 CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
00097 }
00098 void Mutex::unlock() {
00099 CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
00100 }
00101
00102 void Mutex::trylock() {
00103 CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex));
00104 }
00105
00106 #else
00107
00108
00113 struct PODMutex
00114 {
00115 typedef ScopedLock<PODMutex> ScopedLock;
00116
00117 inline void lock();
00118 inline void unlock();
00119 inline void trylock();
00120
00121
00122 pthread_mutex_t mutex;
00123 };
00124
00125 #define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
00126
00127
00128 void PODMutex::lock() {
00129 QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
00130 }
00131 void PODMutex::unlock() {
00132 QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
00133 }
00134
00135 void PODMutex::trylock() {
00136 QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
00137 }
00138
00139
00140 Mutex::Mutex() {
00141 QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0));
00142 }
00143
00144 Mutex::~Mutex(){
00145 QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex));
00146 }
00147
00148 void Mutex::lock() {
00149 QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
00150 }
00151 void Mutex::unlock() {
00152 QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
00153 }
00154
00155 void Mutex::trylock() {
00156 QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
00157 }
00158
00159 #endif // USE_APR
00160
00161 }}
00162
00163
00164
00165 #endif