00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00038 #ifndef BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_
00039 #define BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_
00040 #include "blocxx/BLOCXX_config.h"
00041 #include "blocxx/NonRecursiveMutexLock.hpp"
00042 #include "blocxx/Condition.hpp"
00043 #include "blocxx/Exception.hpp"
00044 #include "blocxx/Array.hpp"
00045
00046 namespace BLOCXX_NAMESPACE
00047 {
00048
00049 BLOCXX_DECLARE_APIEXCEPTION(RWLocker, BLOCXX_COMMON_API);
00051 class BLOCXX_COMMON_API RWLocker
00052 {
00053 public:
00054 RWLocker();
00055 ~RWLocker();
00056 void getReadLock(UInt32 sTimeout, UInt32 usTimeout=0);
00057 void getWriteLock(UInt32 sTimeout, UInt32 usTimeout=0);
00058 void releaseReadLock();
00059 void releaseWriteLock();
00060 private:
00061 void doWakeups();
00062 Condition m_waiting_writers;
00063 Condition m_waiting_readers;
00064
00065 int m_num_waiting_writers;
00066 int m_num_waiting_readers;
00067 int m_readers_next;
00068
00069 NonRecursiveMutex m_guard;
00070
00071
00072 int m_state;
00073
00074 #ifdef BLOCXX_WIN32
00075 #pragma warning (push)
00076 #pragma warning (disable: 4251)
00077 #endif
00078
00079 Array<Thread_t> m_readers;
00080
00081 #ifdef BLOCXX_WIN32
00082 #pragma warning (pop)
00083 #endif
00084
00085 Thread_t m_writer;
00086 };
00088 class BLOCXX_COMMON_API ReadLock
00089 {
00090 public:
00091 ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0)
00092 : m_locker(&locker)
00093 , m_released(false)
00094 {
00095 m_locker->getReadLock(sTimeout, usTimeout);
00096 }
00097 ~ReadLock()
00098 {
00099 release();
00100 }
00101 void lock(UInt32 sTimeout, UInt32 usTimeout=0)
00102 {
00103 if (m_released)
00104 {
00105 m_locker->getReadLock(sTimeout, usTimeout);
00106 m_released = false;
00107 }
00108 }
00109 void release()
00110 {
00111 if (!m_released)
00112 {
00113 m_locker->releaseReadLock();
00114 m_released = true;
00115 }
00116 }
00117 private:
00118 RWLocker* m_locker;
00119 bool m_released;
00120
00121 ReadLock(const ReadLock&);
00122 ReadLock& operator=(const ReadLock&);
00123 };
00125 class BLOCXX_COMMON_API WriteLock
00126 {
00127 public:
00128 WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0)
00129 : m_locker(&locker)
00130 , m_released(false)
00131 {
00132 m_locker->getWriteLock(sTimeout, usTimeout);
00133 }
00134 ~WriteLock()
00135 {
00136 release();
00137 }
00138 void lock(UInt32 sTimeout, UInt32 usTimeout=0)
00139 {
00140 if (m_released)
00141 {
00142 m_locker->getWriteLock(sTimeout, usTimeout);
00143 m_released = false;
00144 }
00145 }
00146 void release()
00147 {
00148 if (!m_released)
00149 {
00150 m_locker->releaseWriteLock();
00151 m_released = true;
00152 }
00153 }
00154 private:
00155 RWLocker* m_locker;
00156 bool m_released;
00157
00158
00159 WriteLock(const WriteLock&);
00160 WriteLock& operator=(const WriteLock&);
00161 };
00162
00163 }
00164
00165 #endif