00001
00002 #ifndef __THREADS_WIN32_PAL_HPP__
00003 #define __THREADS_WIN32_PAL_HPP__
00004
00005 #include <limits.h>
00006
00007 #include <windows.h>
00008 #include <assert.h>
00009
00010
00011 namespace lfc
00012 {
00013 namespace win32PAL
00014 {
00015
00017
00023 namespace threads
00024 {
00025
00026 const int MAX_ERROR_CODE = 1;
00027
00028 enum ErrorCodes
00029 {
00030 errOk,
00031 errGeneric,
00032 };
00033
00034 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00035
00036
00038 DWORD WINAPI __threadProc(void *);
00039
00041 struct __StartThreadInfo
00042 {
00043 void (*proc)(void *);
00044 void *pData;
00045 };
00046
00047
00049 typedef ::HANDLE ThreadHandle;
00051 const ThreadHandle NULL_THREAD_HANDLE = NULL;
00052
00054 typedef ::HANDLE MutexHandle;
00056 const MutexHandle NULL_MUTEX_HANDLE = NULL;
00057
00059 typedef ::HANDLE SemHandle;
00061 const SemHandle NULL_SEM_HANDLE = NULL;
00062
00064 typedef DWORD TLSKey;
00065
00066
00068 const int
00069 priorityMin = THREAD_PRIORITY_LOWEST,
00070 priorityNormal = THREAD_PRIORITY_NORMAL,
00071 priorityMax = THREAD_PRIORITY_HIGHEST;
00072
00073
00075
00078 inline int init()
00079 {
00080 return errOk;
00081 }
00082
00083
00085
00088 inline int cleanup()
00089 {
00090 return errOk;
00091 }
00092
00093
00095
00104 inline int createThread(ThreadHandle &handle, void (*proc)(void *), void *pData)
00105 {
00106 DWORD threadId;
00107
00108 __StartThreadInfo *pInfo = new __StartThreadInfo;
00109 pInfo->proc = proc;
00110 pInfo->pData = pData;
00111
00112 ThreadHandle h = ::CreateThread(NULL, 0, &__threadProc, pInfo, 0,
00113 &threadId);
00114 if(h != NULL)
00115 {
00116 handle = h;
00117 return errOk;
00118 }
00119 else
00120 return errGeneric;
00121 }
00122
00123
00125
00129 inline int closeThread(ThreadHandle &handle)
00130 {
00131 return ::CloseHandle(handle) ? errOk : errGeneric;
00132 }
00133
00134
00136
00144 inline int getCurrentThread(ThreadHandle &handle)
00145 {
00146 ThreadHandle pseudoHandle = ::GetCurrentThread();
00147 ThreadHandle h;
00148
00149 if(::DuplicateHandle(::GetCurrentProcess(), pseudoHandle,
00150 ::GetCurrentProcess(), &h, 0, false, DUPLICATE_SAME_ACCESS))
00151 {
00152 handle = h;
00153 return errOk;
00154 }
00155 else
00156 return errGeneric;
00157 }
00158
00159
00161
00165 inline int destroyThread(const ThreadHandle &handle)
00166 {
00167 return ::TerminateThread(handle, 0) ? errOk : errGeneric;
00168 }
00169
00170
00172
00176 inline int joinThread(const ThreadHandle &handle)
00177 {
00178 if(::WaitForSingleObject(handle, INFINITE) != WAIT_FAILED)
00179 return errOk;
00180 else
00181 return errGeneric;
00182 }
00183
00184
00186
00191 inline int setThreadPriority(const ThreadHandle &handle, int priority)
00192 {
00193 return ::SetThreadPriority(handle, priority) ? errOk : errGeneric;
00194 }
00195
00196
00198
00201 inline int yield()
00202 {
00203 ::Sleep(0);
00204 return errOk;
00205 }
00206
00207
00209
00213 inline int sleep(long miliseconds)
00214 {
00215 ::Sleep(miliseconds);
00216 return errOk;
00217 }
00218
00219
00221
00225 inline int allocTLS(TLSKey &key)
00226 {
00227 TLSKey k = ::TlsAlloc();
00228 if(k != 0xFFFFFFFF)
00229 {
00230 key = k;
00231 return errOk;
00232 }
00233 else
00234 return errGeneric;
00235 }
00236
00237
00239
00244 inline int freeTLS(TLSKey key)
00245 {
00246 return ::TlsFree(key) ? errOk : errGeneric;
00247 }
00248
00249
00251
00256 inline int setTLS(TLSKey key, void *value)
00257 {
00258 return ::TlsSetValue(key, value) ? errOk : errGeneric;
00259 }
00260
00261
00263
00268 inline int getTLS(TLSKey key, void *&value)
00269 {
00270 void *v = ::TlsGetValue(key);
00271 if(::GetLastError() == NO_ERROR)
00272 {
00273 value = v;
00274 return errOk;
00275 }
00276 else
00277 return errGeneric;
00278 }
00279
00280
00282
00287 inline int createMutex(MutexHandle &handle)
00288 {
00289 MutexHandle h = ::CreateMutex(NULL, false, NULL);
00290 if(h != NULL)
00291 {
00292 handle = h;
00293 return errOk;
00294 }
00295 else
00296 return errGeneric;
00297 }
00298
00299
00301
00305 inline int closeMutex(MutexHandle &handle)
00306 {
00307 return ::CloseHandle(handle) ? errOk : errGeneric;
00308 }
00309
00310
00312
00317 inline int lockMutex(MutexHandle &handle)
00318 {
00319 if( ::WaitForSingleObject(handle, INFINITE) != WAIT_FAILED)
00320 return errOk;
00321 else
00322 return errGeneric;
00323 }
00324
00326
00332 inline int tryLockMutex(MutexHandle &handle, bool &bLocked)
00333 {
00334 DWORD retCode = ::WaitForSingleObject(handle, 0);
00335
00336 if(retCode != WAIT_FAILED)
00337 {
00338 bLocked = (retCode != WAIT_TIMEOUT);
00339 return errOk;
00340 }
00341 else
00342 return errGeneric;
00343 }
00344
00346
00350 inline int unlockMutex(MutexHandle &handle)
00351 {
00352 return ::ReleaseMutex(handle) ? errOk : errGeneric;
00353 }
00354
00355
00357
00363 inline int createSemaphore(SemHandle &handle, long count)
00364 {
00365 SemHandle h = ::CreateSemaphore(NULL, count, LONG_MAX, NULL);
00366 if(h != NULL)
00367 {
00368 handle = h;
00369 return errOk;
00370 }
00371 else
00372 return errGeneric;
00373 }
00374
00375
00377
00381 inline int closeSemaphore(SemHandle &handle)
00382 {
00383 return ::CloseHandle(handle) ? errOk : errGeneric;
00384 }
00385
00386
00388
00392 inline int waitSemaphore(SemHandle &handle)
00393 {
00394 DWORD retCode = ::WaitForSingleObject(handle, INFINITE);
00395
00396 if(retCode != WAIT_FAILED)
00397 return errOk;
00398 else
00399 return errGeneric;
00400 }
00401
00403
00408 inline int tryWaitSemaphore(SemHandle &handle, bool &bLocked)
00409 {
00410 DWORD retCode = ::WaitForSingleObject(handle, 0 );
00411
00412 if(retCode != WAIT_FAILED)
00413 {
00414 bLocked = (retCode != WAIT_TIMEOUT);
00415 return errOk;
00416 }
00417 else
00418 return errGeneric;
00419 }
00420
00422
00426 inline int postSemaphore(SemHandle &handle)
00427 {
00428 return ::ReleaseSemaphore(handle, 1, NULL) ? errOk : errGeneric;
00429 }
00430
00431
00433
00436 inline const char *message(int index)
00437 {
00438 assert(index >= 0 && index <= MAX_ERROR_CODE);
00439 return messagesTable[index];
00440 }
00441
00442
00443 }
00444 }
00445
00446 namespace pal = win32PAL;
00447
00448 }
00449
00450
00451 #endif // __THREADS_WIN32_PAL_HPP__