00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef IXE_Lock_H
00025 #define IXE_Lock_H
00026
00027
00028 #include "platform.h"
00029
00030
00031 #ifdef _WIN32
00032 # include <windows.h>
00033 #else
00034 # include <pthread.h>
00035 # include <cerrno>
00036 #endif
00037
00038 namespace IXE {
00039
00040 #ifdef _WIN32
00041
00042 #define TRESULT unsigned int __stdcall
00043 #define CriticalSection CRITICAL_SECTION
00044
00045 struct Condition
00046 {
00047 Condition() : _c(CreateEvent(NULL, FALSE, FALSE, NULL)) { }
00048 Condition(Condition const&) {
00049 _c = CreateEvent(NULL, FALSE, FALSE, NULL); }
00050 ~Condition() { CloseHandle(_c); }
00051 inline void notify() { SetEvent(_c); }
00052 bool wait() {
00053 WaitForSingleObject(_c, INFINITE);
00054 return true;
00055 }
00056
00057 HANDLE _c;
00058 };
00059
00060 typedef Condition SimpleCondition;
00061
00062 #define ConditionWait(condition, lock) { \
00063 LeaveCriticalSection(lock); \
00064 WaitForSingleObject((condition)._c, INFINITE); \
00065 EnterCriticalSection(lock); }
00066
00067 #define ConditionWaitInterval(condition, lock, msec, nsec, result) { \
00068 LeaveCriticalSection(lock); \
00069 result = WaitForSingleObject((condition)._c, msec); \
00070 EnterCriticalSection(lock); }
00071
00072 #else // !_WIN32
00073
00074 #define TRESULT void*
00075 #define WAIT_TIMEOUT ETIMEDOUT
00076
00077 struct Condition
00078 {
00079 Condition() { ::pthread_cond_init(&_c, 0); }
00080 Condition(Condition const&) {
00081 ::pthread_cond_init(&_c, 0); }
00082 ~Condition() { ::pthread_cond_destroy(&_c); }
00083 inline void notify() { ::pthread_cond_signal(&_c); }
00084
00085 ::pthread_cond_t _c;
00086 };
00087
00094 struct SimpleCondition
00095 {
00096 SimpleCondition() {
00097 ::pthread_mutex_init(&_c, 0);
00098 ::pthread_mutex_lock(&_c);
00099 }
00100 SimpleCondition(SimpleCondition const&) {
00101 ::pthread_mutex_init(&_c, 0);
00102 ::pthread_mutex_lock(&_c);
00103 }
00104 ~SimpleCondition() {
00105 ::pthread_mutex_unlock(&_c);
00106 ::pthread_mutex_destroy(&_c);
00107 }
00108 inline void notify() { ::pthread_mutex_unlock(&_c); }
00109 bool wait() {
00110 ::pthread_mutex_lock(&_c);
00111 return true;
00112 }
00113
00114 ::pthread_mutex_t _c;
00115 };
00116
00117 #define ConditionWait(condition, lock) \
00118 ::pthread_cond_wait(&(condition._c), lock)
00119
00120 #define ConditionWaitInterval(condition, lock, msec, nsec, result) { \
00121 struct timespec future; \
00122 future.tv_sec = ::time(0) + (msec) / 1000; \
00123 future.tv_nsec = nsec; \
00124 result = ::pthread_cond_timedwait(&(condition._c), lock, &future); }
00125
00126
00127 #define CriticalSection ::pthread_mutex_t
00128 #define InitializeCriticalSection(x) ::pthread_mutex_init(x, 0)
00129 #define DeleteCriticalSection ::pthread_mutex_destroy
00130 #define EnterCriticalSection ::pthread_mutex_lock
00131 #define LeaveCriticalSection ::pthread_mutex_unlock
00132 #define ExitThread ::pthread_exit
00133 #define TerminateThread(x, y) ::pthread_cancel(x)
00134 #define GetCurrentThread ::pthread_self
00135
00136 #endif // _WIN32
00137
00141 struct Lock
00142 {
00143 Lock() { InitializeCriticalSection(&_lock); }
00144 Lock(Lock const&) { InitializeCriticalSection(&_lock); }
00145
00146 ~Lock() { DeleteCriticalSection(&_lock); }
00147
00148 void In() { EnterCriticalSection(&_lock); }
00149
00150 void Out() { LeaveCriticalSection(&_lock); }
00151
00152 CriticalSection _lock;
00153 };
00154
00155 template <typename T>
00156 class Locked : public Lock
00157 {
00158 public:
00159
00160 Locked() { }
00161
00162 Locked(T value) :
00163 value(value)
00164 { }
00165
00166 T value;
00167
00168 inline operator T() const { return value; }
00169 inline operator T*() const { return &value; }
00170
00171 T& operator *() { return value; }
00172 T* operator ->() { return &value; }
00173 };
00174
00175
00176
00177 #define Locking(m, stat) EnterCriticalSection(&(m)._lock); \
00178 stat; \
00179 LeaveCriticalSection(&(m)._lock);
00180
00183 class LockUp
00184 {
00185 public:
00186 CriticalSection& mutex;
00187
00188 public:
00189 LockUp(CriticalSection& mutex) :
00190 mutex(mutex)
00191 {
00192 EnterCriticalSection(&mutex);
00193 }
00194
00195 LockUp(Lock& lock) :
00196 mutex(lock._lock)
00197 {
00198 EnterCriticalSection(&mutex);
00199 }
00200
00201 ~LockUp() { LeaveCriticalSection(&mutex); }
00202 };
00203
00204 }
00205
00206 #endif // IXE_Lock_H