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