/home/aconway/svn/qpid/cpp/src/qpid/sys/Mutex.h

00001 #ifndef _sys_Mutex_h
00002 #define _sys_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 #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 // APR ================================================================
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 // POSIX ================================================================
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     // Must be public to be a POD:
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  

Generated on Tue Apr 17 14:22:03 2007 for Qpid by  doxygen 1.4.7