/home/aconway/svn/qpid/cpp/lib/common/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 
00039 template <class L>
00040 class ScopedLock
00041 {
00042   public:
00043     ScopedLock(L& l) : mutex(l) { l.lock(); }
00044     ~ScopedLock() { mutex.unlock(); }
00045   private:
00046     L& mutex;
00047 };
00048 
00052 class Mutex : private boost::noncopyable {
00053   public:
00054     typedef ScopedLock<Mutex> ScopedLock;
00055     
00056     inline Mutex();
00057     inline ~Mutex();
00058     inline void lock();
00059     inline void unlock();
00060     inline void trylock();
00061 
00062   protected:
00063 #ifdef USE_APR
00064     apr_thread_mutex_t* mutex;
00065 #else
00066     pthread_mutex_t mutex;
00067 #endif
00068 };
00069 
00070 #ifdef USE_APR
00071 // APR ================================================================
00072 
00073 Mutex::Mutex() {
00074     CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get()));
00075 }
00076 
00077 Mutex::~Mutex(){
00078     CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
00079 }
00080 
00081 void Mutex::lock() {
00082     CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
00083 }
00084 void Mutex::unlock() {
00085     CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
00086 }
00087 
00088 void Mutex::trylock() {
00089     CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex));
00090 }
00091 
00092 #else
00093 // POSIX ================================================================
00094 
00099 struct PODMutex 
00100 {
00101     typedef ScopedLock<PODMutex> ScopedLock;
00102 
00103     inline void lock();
00104     inline void unlock();
00105     inline void trylock();
00106 
00107     // Must be public to be a POD:
00108     pthread_mutex_t mutex;
00109 };
00110 
00111 #define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
00112 
00113 
00114 void PODMutex::lock() {
00115     QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
00116 }
00117 void PODMutex::unlock() {
00118     QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
00119 }
00120 
00121 void PODMutex::trylock() {
00122     QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
00123 }
00124 
00125 
00126 Mutex::Mutex() {
00127     QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0));
00128 }
00129 
00130 Mutex::~Mutex(){
00131     QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex));
00132 }
00133 
00134 void Mutex::lock() {
00135     QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
00136 }
00137 void Mutex::unlock() {
00138     QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
00139 }
00140 
00141 void Mutex::trylock() {
00142     QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
00143 }
00144 
00145 #endif // USE_APR
00146 
00147 }}
00148 
00149 
00150 
00151 #endif  

Generated on Thu Jan 25 11:48:13 2007 for Qpid by  doxygen 1.5.1