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
00036 #ifndef OW_RWLOCKER_HPP_INCLUDE_GUARD_
00037 #define OW_RWLOCKER_HPP_INCLUDE_GUARD_
00038 #include "OW_config.h"
00039 #include "OW_NonRecursiveMutexLock.hpp"
00040 #include "OW_Condition.hpp"
00041 #include "OW_Exception.hpp"
00042 #include "OW_Array.hpp"
00043
00044 namespace OW_NAMESPACE
00045 {
00046
00047 OW_DECLARE_APIEXCEPTION(RWLocker, OW_COMMON_API);
00049 class OW_COMMON_API RWLocker
00050 {
00051 public:
00052 RWLocker();
00053 ~RWLocker();
00054 void getReadLock(UInt32 sTimeout, UInt32 usTimeout=0);
00055 void getWriteLock(UInt32 sTimeout, UInt32 usTimeout=0);
00056 void releaseReadLock();
00057 void releaseWriteLock();
00058 private:
00059 void doWakeups();
00060 Condition m_waiting_writers;
00061 Condition m_waiting_readers;
00062
00063 int m_num_waiting_writers;
00064 int m_num_waiting_readers;
00065 int m_readers_next;
00066
00067 NonRecursiveMutex m_guard;
00068
00069
00070 int m_state;
00071
00072 #ifdef OW_WIN32
00073 #pragma warning (push)
00074 #pragma warning (disable: 4251)
00075 #endif
00076
00077 Array<Thread_t> m_readers;
00078
00079 #ifdef OW_WIN32
00080 #pragma warning (pop)
00081 #endif
00082
00083 Thread_t m_writer;
00084 };
00086 class OW_COMMON_API ReadLock
00087 {
00088 public:
00089 ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0)
00090 : m_locker(&locker)
00091 , m_released(false)
00092 {
00093 m_locker->getReadLock(sTimeout, usTimeout);
00094 }
00095 ~ReadLock()
00096 {
00097 release();
00098 }
00099 void lock(UInt32 sTimeout, UInt32 usTimeout=0)
00100 {
00101 if (m_released)
00102 {
00103 m_locker->getReadLock(sTimeout, usTimeout);
00104 m_released = false;
00105 }
00106 }
00107 void release()
00108 {
00109 if (!m_released)
00110 {
00111 m_locker->releaseReadLock();
00112 m_released = true;
00113 }
00114 }
00115 private:
00116 RWLocker* m_locker;
00117 bool m_released;
00118
00119 ReadLock(const ReadLock&);
00120 ReadLock& operator=(const ReadLock&);
00121 };
00123 class OW_COMMON_API WriteLock
00124 {
00125 public:
00126 WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0)
00127 : m_locker(&locker)
00128 , m_released(false)
00129 {
00130 m_locker->getWriteLock(sTimeout, usTimeout);
00131 }
00132 ~WriteLock()
00133 {
00134 release();
00135 }
00136 void lock(UInt32 sTimeout, UInt32 usTimeout=0)
00137 {
00138 if (m_released)
00139 {
00140 m_locker->getWriteLock(sTimeout, usTimeout);
00141 m_released = false;
00142 }
00143 }
00144 void release()
00145 {
00146 if (!m_released)
00147 {
00148 m_locker->releaseWriteLock();
00149 m_released = true;
00150 }
00151 }
00152 private:
00153 RWLocker* m_locker;
00154 bool m_released;
00155
00156
00157 WriteLock(const WriteLock&);
00158 WriteLock& operator=(const WriteLock&);
00159 };
00160
00161 }
00162
00163 #endif