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