1 /* Threads.c -- multithreading library 2 2013-11-12 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #ifndef _WIN32_WCE 7 #include <process.h> 8 #endif 9 10 #include "Threads.h" 11 12 static WRes GetError() 13 { 14 DWORD res = GetLastError(); 15 return (res) ? (WRes)(res) : 1; 16 } 17 18 WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } 19 WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } 20 21 WRes HandlePtr_Close(HANDLE *p) 22 { 23 if (*p != NULL) 24 if (!CloseHandle(*p)) 25 return GetError(); 26 *p = NULL; 27 return 0; 28 } 29 30 WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } 31 32 WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) 33 { 34 /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ 35 36 #ifdef UNDER_CE 37 38 DWORD threadId; 39 *p = CreateThread(0, 0, func, param, 0, &threadId); 40 41 #else 42 43 unsigned threadId; 44 *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); 45 46 #endif 47 48 /* maybe we must use errno here, but probably GetLastError() is also OK. */ 49 return HandleToWRes(*p); 50 } 51 52 WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) 53 { 54 *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); 55 return HandleToWRes(*p); 56 } 57 58 WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } 59 WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } 60 61 WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } 62 WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } 63 WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } 64 WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } 65 66 67 WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) 68 { 69 *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); 70 return HandleToWRes(*p); 71 } 72 73 static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) 74 { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } 75 WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) 76 { return Semaphore_Release(p, (LONG)num, NULL); } 77 WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } 78 79 WRes CriticalSection_Init(CCriticalSection *p) 80 { 81 /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ 82 #ifdef _MSC_VER 83 __try 84 #endif 85 { 86 InitializeCriticalSection(p); 87 /* InitializeCriticalSectionAndSpinCount(p, 0); */ 88 } 89 #ifdef _MSC_VER 90 __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } 91 #endif 92 return 0; 93 } 94