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 #ifndef _CSP_KERNEL_Mutex_H
00030 #define _CSP_KERNEL_Mutex_H
00031
00032
00033 #ifdef _WIN32
00034 #include <windows.h>
00035 #else
00036 #include <pthread.h>
00037 #endif
00038
00039
00040 CSP_NAMESPACE_BEGIN(csp);
00041
00042
00048 class CSP_API Mutex
00049 {
00050 public:
00055 class GlobalData;
00056
00063 Mutex(GlobalData* globalData) :
00064 m_globalData(globalData)
00065 {
00066 m_depth = 0;
00067 m_thread = -1;
00068 }
00069
00073 virtual ~Mutex() { while (m_depth) release(); }
00074
00078 bool iHoldIt() const
00079 {
00080 return ((m_thread == currentThread()) && (m_depth > 0));
00081 }
00082
00090 void acquire()
00091 {
00092 if (m_thread != currentThread())
00093 {
00094 m_globalData->lock();
00095 m_thread = currentThread();
00096
00097 assert(m_depth == 0);
00098 }
00099 m_depth++;
00100 }
00101
00110 void release()
00111 {
00112 assert(iHoldIt());
00113 m_depth--;
00114
00115 if (m_depth == 0)
00116 {
00117 m_thread = -1;
00118 m_globalData->unlock();
00119 }
00120 }
00121
00133 class CSP_API GlobalData
00134 {
00135 private:
00136 #ifndef _WIN32
00137 pthread_mutex_t m_mutex;
00138 #else
00139 HANDLE m_mutex;
00140 #endif
00141
00142 public:
00143 friend class Mutex;
00144
00146 GlobalData()
00147 {
00148 #ifdef _WIN32
00149 m_mutex = CreateMutex(0, FALSE, 0);
00150 #else
00151 pthread_mutex_init(&m_mutex, 0);
00152 #endif
00153 }
00154
00156 ~GlobalData()
00157 {
00158 #ifdef _WIN32
00159 CloseHandle(m_mutex);
00160 #else
00161 pthread_mutex_destroy(&m_mutex);
00162 #endif
00163 }
00164
00166 void lock()
00167 {
00168 #ifdef _WIN32
00169 WaitForSingleObject(m_mutex, INFINITE);
00170 #else
00171 pthread_mutex_lock(&m_mutex);
00172 #endif
00173 }
00174
00176 void unlock()
00177 {
00178 #ifdef _WIN32
00179 ReleaseMutex(m_mutex);
00180 #else
00181 pthread_mutex_unlock(&m_mutex);
00182 #endif
00183 }
00184
00185 private:
00186
00187 GlobalData(const GlobalData&);
00188 };
00189
00190 private:
00192 int currentThread() const
00193 {
00194 #ifdef _WIN32
00195 return GetCurrentThreadId();
00196 #else
00197 return pthread_self();
00198 #endif
00199 }
00200
00202 Mutex::GlobalData* m_globalData;
00203
00206 int m_thread;
00207
00210 int m_depth;
00211 };
00212
00213
00214 CSP_NAMESPACE_END(csp);
00215
00216
00217 #endif // _CSP_KERNEL_Mutex_H
00218
00219
00220
00221