|
1 /* Threads.c */ |
|
2 |
|
3 #include "Threads.h" |
|
4 #include <process.h> |
|
5 |
|
6 HRes GetError() |
|
7 { |
|
8 DWORD res = GetLastError(); |
|
9 return (res) ? (HRes)(res) : SZE_FAIL; |
|
10 } |
|
11 |
|
12 HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); } |
|
13 HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); } |
|
14 |
|
15 HRes MyCloseHandle(HANDLE *h) |
|
16 { |
|
17 if (*h != NULL) |
|
18 if (!CloseHandle(*h)) |
|
19 return GetError(); |
|
20 *h = NULL; |
|
21 return SZ_OK; |
|
22 } |
|
23 |
|
24 HRes 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 |
|
34 HRes WaitObject(HANDLE h) |
|
35 { |
|
36 return (HRes)WaitForSingleObject(h, INFINITE); |
|
37 } |
|
38 |
|
39 HRes Thread_Wait(CThread *thread) |
|
40 { |
|
41 if (thread->handle == NULL) |
|
42 return 1; |
|
43 return WaitObject(thread->handle); |
|
44 } |
|
45 |
|
46 HRes Thread_Close(CThread *thread) |
|
47 { |
|
48 return MyCloseHandle(&thread->handle); |
|
49 } |
|
50 |
|
51 HRes 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 |
|
57 HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) |
|
58 { return Event_Create(p, TRUE, initialSignaled); } |
|
59 HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) |
|
60 { return ManualResetEvent_Create(p, 0); } |
|
61 |
|
62 HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) |
|
63 { return Event_Create(p, FALSE, initialSignaled); } |
|
64 HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) |
|
65 { return AutoResetEvent_Create(p, 0); } |
|
66 |
|
67 HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); } |
|
68 HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); } |
|
69 HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } |
|
70 HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } |
|
71 |
|
72 |
|
73 HRes 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 |
|
79 HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) |
|
80 { |
|
81 return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); |
|
82 } |
|
83 HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) |
|
84 { |
|
85 return Semaphore_Release(p, (LONG)releaseCount, NULL); |
|
86 } |
|
87 HRes Semaphore_Release1(CSemaphore *p) |
|
88 { |
|
89 return Semaphore_ReleaseN(p, 1); |
|
90 } |
|
91 |
|
92 HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } |
|
93 HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } |
|
94 |
|
95 HRes 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 |