1/* Threads.c */ 2 3#include "Threads.h" 4#include <process.h> 5 6HRes GetError() 7{ 8 DWORD res = GetLastError(); 9 return (res) ? (HRes)(res) : SZE_FAIL; 10} 11 12HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); } 13HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); } 14 15HRes MyCloseHandle(HANDLE *h) 16{ 17 if (*h != NULL) 18 if (!CloseHandle(*h)) 19 return GetError(); 20 *h = NULL; 21 return SZ_OK; 22} 23 24HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) 25{ 26 unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ 27 thread->handle = 28 /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */ 29 (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId); 30 /* maybe we must use errno here, but probably GetLastError() is also OK. */ 31 return BoolToHRes(thread->handle != 0); 32} 33 34HRes WaitObject(HANDLE h) 35{ 36 return (HRes)WaitForSingleObject(h, INFINITE); 37} 38 39HRes Thread_Wait(CThread *thread) 40{ 41 if (thread->handle == NULL) 42 return 1; 43 return WaitObject(thread->handle); 44} 45 46HRes Thread_Close(CThread *thread) 47{ 48 return MyCloseHandle(&thread->handle); 49} 50 51HRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) 52{ 53 p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL); 54 return BoolToHRes(p->handle != 0); 55} 56 57HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) 58 { return Event_Create(p, TRUE, initialSignaled); } 59HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) 60 { return ManualResetEvent_Create(p, 0); } 61 62HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) 63 { return Event_Create(p, FALSE, initialSignaled); } 64HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) 65 { return AutoResetEvent_Create(p, 0); } 66 67HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); } 68HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); } 69HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } 70HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } 71 72 73HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) 74{ 75 p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL); 76 return BoolToHRes(p->handle != 0); 77} 78 79HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) 80{ 81 return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); 82} 83HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) 84{ 85 return Semaphore_Release(p, (LONG)releaseCount, NULL); 86} 87HRes Semaphore_Release1(CSemaphore *p) 88{ 89 return Semaphore_ReleaseN(p, 1); 90} 91 92HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } 93HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } 94 95HRes CriticalSection_Init(CCriticalSection *p) 96{ 97 /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ 98 __try 99 { 100 InitializeCriticalSection(p); 101 /* InitializeCriticalSectionAndSpinCount(p, 0); */ 102 } 103 __except (EXCEPTION_EXECUTE_HANDLER) { return SZE_OUTOFMEMORY; } 104 return SZ_OK; 105} 106 107