Apache Qpid - AMQP Messaging for Java JMS, C++, Python, Ruby, and .NET Apache Qpid Documentation
qpid/sys/windows/Mutex.h
Go to the documentation of this file.
00001 #ifndef _sys_windows_Mutex_h
00002 #define _sys_windows_Mutex_h
00003 
00004 /*
00005  *
00006  * Copyright (c) 2008 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 "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();  // will write-lock
00074     inline void rlock();  // will read-lock
00075     inline void unlock();
00076     inline void trywlock();  // will write-try
00077     inline void tryrlock();  // will read-try
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     // Must be public to be a POD:
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;    // Remember this thread has write lock held.
00146 }
00147 
00148 void RWlock::rlock() {
00149     bool &writer = write();
00150     rwMutex.lock_shared();
00151     writer = false;   // Remember this thread has shared lock held.
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     // shared_mutex::try_lock() seems to not be available... emulate it with
00165     // a timed lock().
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     // Accessing thread-specific and stack-local info, so no locks needed.
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  

Qpid C++ API Reference
Generated on Mon Aug 22 2011 for Qpid C++ Client API by doxygen 1.7.4