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