00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef READWRITELOCK_H_INCLUDED
00024 #define READWRITELOCK_H_INCLUDED
00025
00026 #pragma once
00027
00028 #include "stdafx.h"
00029 #include "windows.h"
00030
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class MicoleBusReadWriteLock
00055 {
00056 CMutex m_Access;
00057 int m_Readers;
00058 CMutex m_WriterMutex;
00059 CEvent m_CanRead;
00060 CEvent m_CanWrite;
00061
00062 MicoleBusReadWriteLock( MicoleBusReadWriteLock const& );
00063 void operator=( MicoleBusReadWriteLock const& );
00064
00065 public:
00066 MicoleBusReadWriteLock();
00067
00068 bool LockRead( DWORD Timeout = INFINITE );
00069 bool LockWrite( DWORD Timeout = INFINITE );
00070 bool UnlockRead( DWORD Timeout = INFINITE );
00071 bool UnlockWrite( DWORD Timeout = INFINITE );
00072 };
00073
00074
00075 #pragma warning( disable: 4786 )
00076 #include <map>
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 class MicoleBusReadWriteLockEx
00094 {
00095 struct KThreadInfo
00096 {
00097 int ReadCount;
00098 int WriteCount;
00099
00100 bool IsReader() { return ReadCount > 0; };
00101 bool IsWriter() { return WriteCount > 0; };
00102 };
00103
00104 typedef std::map<DWORD, KThreadInfo> KThreadMap;
00105 KThreadMap m_Threads;
00106
00107
00108
00109 int m_TotalReaderThreads;
00110 int m_TotalWriterThreads;
00111
00112 CMutex m_Access;
00113 CMutex m_WriterMutex;
00114 CEvent m_CanRead;
00115 CEvent m_CanWrite;
00116
00117 void IncReaders()
00118 {
00119 ++m_TotalReaderThreads;
00120 ResetEvent(m_CanWrite);
00121 };
00122
00123 void DecReaders()
00124 {
00125 if (--m_TotalReaderThreads == 0)
00126 SetEvent(m_CanWrite);
00127 };
00128
00129 void IncWriters()
00130 {
00131 ++m_TotalWriterThreads;
00132 ResetEvent(m_CanRead);
00133 };
00134
00135 void DecWriters()
00136 {
00137 if (--m_TotalWriterThreads == 0)
00138 SetEvent(m_CanRead);
00139 };
00140
00141 MicoleBusReadWriteLockEx( MicoleBusReadWriteLockEx const& );
00142 void operator=( MicoleBusReadWriteLockEx const& );
00143
00144 public:
00145 MicoleBusReadWriteLockEx();
00146
00147 bool LockRead( DWORD Timeout = INFINITE );
00148 bool LockWrite( DWORD Timeout = INFINITE );
00149 bool UnlockRead( DWORD Timeout = INFINITE );
00150 bool UnlockWrite( DWORD Timeout = INFINITE );
00151
00152 };
00153
00154
00155
00156
00157
00158
00159 template <class T>
00160 class KReadLockTempl
00161 {
00162 bool m_bLocked;
00163 T& m_Lock;
00164
00165 KReadLockTempl( KReadLockTempl const& );
00166 void operator=( KReadLockTempl const& );
00167
00168
00169 public:
00170 KReadLockTempl(T& Lock, bool bInitialLock = true)
00171 :
00172 m_Lock(Lock),
00173 m_bLocked(false)
00174 {
00175 if (bInitialLock)
00176 {
00177 VERIFY(m_Lock.LockRead());
00178 m_bLocked = true;
00179 }
00180 };
00181
00182 ~KReadLockTempl()
00183 {
00184 if (m_bLocked)
00185 VERIFY(m_Lock.UnlockRead());
00186 };
00187
00188 bool Lock(DWORD Timeout = INFINITE)
00189 {
00190 ASSERT(!m_bLocked);
00191 m_bLocked = m_Lock.LockRead(Timeout);
00192 return m_bLocked;
00193 };
00194
00195 bool Unlock(DWORD Timeout = INFINITE)
00196 {
00197 ASSERT(m_bLocked);
00198 m_bLocked = !m_Lock.UnlockRead(Timeout);
00199 return !m_bLocked;
00200 }
00201 };
00202
00203
00204
00205
00206
00207
00208 template <class T>
00209 class KWriteLockTempl
00210 {
00211 bool m_bLocked;
00212 T& m_Lock;
00213
00214 KWriteLockTempl( KWriteLockTempl const& );
00215 void operator=( KWriteLockTempl const& );
00216
00217
00218 public:
00219 KWriteLockTempl(T& Lock, bool bInitialLock = true)
00220 :
00221 m_Lock(Lock),
00222 m_bLocked(false)
00223 {
00224 if (bInitialLock)
00225 {
00226 VERIFY(m_Lock.LockWrite());
00227 m_bLocked = true;
00228 }
00229 };
00230
00231 ~KWriteLockTempl()
00232 {
00233 if (m_bLocked)
00234 VERIFY(m_Lock.UnlockWrite());
00235 };
00236
00237 bool Lock(DWORD Timeout = INFINITE)
00238 {
00239 ASSERT(!m_bLocked);
00240 m_bLocked = m_Lock.LockWrite(Timeout);
00241 return m_bLocked;
00242 };
00243
00244 bool Unlock(DWORD Timeout = INFINITE)
00245 {
00246 ASSERT(m_bLocked);
00247 m_bLocked = !m_Lock.UnlockWrite(Timeout);
00248 return !m_bLocked;
00249 }
00250 };
00251
00252 typedef KReadLockTempl<MicoleBusReadWriteLock> KReadLock;
00253 typedef KWriteLockTempl<MicoleBusReadWriteLock> KWriteLock;
00254 typedef KReadLockTempl<MicoleBusReadWriteLockEx> KReadLockEx;
00255 typedef KWriteLockTempl<MicoleBusReadWriteLockEx> KWriteLockEx;
00256
00257
00258 #endif //READWRITELOCK_H_INCLUDED