00001 #ifndef _sys_windows_Mutex_h
00002 #define _sys_windows_Mutex_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qpid/sys/windows/check.h"
00023
00024 #include <boost/version.hpp>
00025 #if (BOOST_VERSION < 103500)
00026 #error The Windows port requires Boost version 1.35.0 or later
00027 #endif
00028
00029 #include <boost/noncopyable.hpp>
00030 #include <boost/thread/recursive_mutex.hpp>
00031 #include <boost/thread/shared_mutex.hpp>
00032 #include <boost/thread/thread_time.hpp>
00033 #include <boost/thread/tss.hpp>
00034
00035 namespace qpid {
00036 namespace sys {
00037
00038 class Condition;
00039
00043 class Mutex : private boost::noncopyable {
00044 friend class Condition;
00045
00046 public:
00047 typedef ::qpid::sys::ScopedLock<Mutex> ScopedLock;
00048 typedef ::qpid::sys::ScopedUnlock<Mutex> ScopedUnlock;
00049
00050 inline Mutex();
00051 inline ~Mutex();
00052 inline void lock();
00053 inline void unlock();
00054 inline bool trylock();
00055
00056
00057 protected:
00058 boost::recursive_mutex mutex;
00059 };
00060
00064 class RWlock : private boost::noncopyable {
00065 friend class Condition;
00066
00067 public:
00068 typedef ::qpid::sys::ScopedRlock<RWlock> ScopedRlock;
00069 typedef ::qpid::sys::ScopedWlock<RWlock> ScopedWlock;
00070
00071 inline RWlock();
00072 inline ~RWlock();
00073 inline void wlock();
00074 inline void rlock();
00075 inline void unlock();
00076 inline void trywlock();
00077 inline void tryrlock();
00078
00079 protected:
00080 boost::shared_mutex rwMutex;
00081 boost::thread_specific_ptr<bool> haveWrite;
00082
00083 inline bool &write (void);
00084 };
00085
00086
00091 struct PODMutex
00092 {
00093 typedef ::qpid::sys::ScopedLock<PODMutex> ScopedLock;
00094
00095 inline void lock();
00096 inline void unlock();
00097 inline bool trylock();
00098
00099
00100 boost::recursive_mutex mutex;
00101 };
00102
00103 #define QPID_MUTEX_INITIALIZER 0
00104
00105 void PODMutex::lock() {
00106 mutex.lock();
00107 }
00108
00109 void PODMutex::unlock() {
00110 mutex.unlock();
00111 }
00112
00113 bool PODMutex::trylock() {
00114 return mutex.try_lock();
00115 }
00116
00117 Mutex::Mutex() {
00118 }
00119
00120 Mutex::~Mutex(){
00121 }
00122
00123 void Mutex::lock() {
00124 mutex.lock();
00125 }
00126
00127 void Mutex::unlock() {
00128 mutex.unlock();
00129 }
00130
00131 bool Mutex::trylock() {
00132 return mutex.try_lock();
00133 }
00134
00135
00136 RWlock::RWlock() {
00137 }
00138
00139 RWlock::~RWlock(){
00140 }
00141
00142 void RWlock::wlock() {
00143 bool &writer = write();
00144 rwMutex.lock();
00145 writer = true;
00146 }
00147
00148 void RWlock::rlock() {
00149 bool &writer = write();
00150 rwMutex.lock_shared();
00151 writer = false;
00152 }
00153
00154 void RWlock::unlock() {
00155 bool &writer = write();
00156 if (writer)
00157 rwMutex.unlock();
00158 else
00159 rwMutex.unlock_shared();
00160 }
00161
00162 void RWlock::trywlock() {
00163 bool &writer = write();
00164
00165
00166 boost::system_time now = boost::get_system_time();
00167 if (rwMutex.timed_lock(now))
00168 writer = true;
00169 }
00170
00171 void RWlock::tryrlock() {
00172 bool &writer = write();
00173 if (rwMutex.try_lock_shared())
00174 writer = false;
00175 }
00176
00177 bool & RWlock::write (void) {
00178
00179 bool *writePtr = haveWrite.get();
00180 if (writePtr == 0) {
00181 writePtr = new bool(false);
00182 haveWrite.reset(writePtr);
00183 }
00184 return *writePtr;
00185 }
00186
00187 }}
00188 #endif