/usr/share/cruisecontrol-bin-2.6.1/projects/qpid-trunk/cpp/src/qpid/sys/posix/Mutex.h

00001 #ifndef _sys_posix_Mutex_h
00002 #define _sys_posix_Mutex_h
00003 
00004 /*
00005  *
00006  * Copyright (c) 2006 The Apache Software Foundation
00007  *
00008  * Licensed under the Apache License, Version 2.0 (the "License");
00009  * you may not use this file except in compliance with the License.
00010  * You may obtain a copy of the License at
00011  *
00012  *    http://www.apache.org/licenses/LICENSE-2.0
00013  *
00014  * Unless required by applicable law or agreed to in writing, software
00015  * distributed under the License is distributed on an "AS IS" BASIS,
00016  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00017  * See the License for the specific language governing permissions and
00018  * limitations under the License.
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();  // will write-lock
00066     inline void rlock();  // will read-lock
00067     inline void unlock();
00068     inline void trywlock();  // will write-try
00069     inline void tryrlock();  // will read-try
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     // Must be public to be a POD:
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  

Generated on Thu Apr 10 11:08:18 2008 for Qpid by  doxygen 1.4.7