1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 /* Threads.c -- multithreading library
31 #include "vogl_core.h"
32 #include "lzma_Threads.h"
38 static WRes GetError()
40 DWORD res = GetLastError();
41 return (res) ? (WRes)(res) : 1;
44 WRes HandleToWRes(HANDLE h)
46 return (h != 0) ? 0 : GetError();
48 WRes BOOLToWRes(BOOL v)
50 return v ? 0 : GetError();
53 static WRes MyCloseHandle(HANDLE *h)
62 WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE(THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
64 unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
66 /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
67 (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
68 /* maybe we must use errno here, but probably GetLastError() is also OK. */
69 return HandleToWRes(thread->handle);
72 WRes WaitObject(HANDLE h)
74 return (WRes)WaitForSingleObject(h, INFINITE);
77 WRes Thread_Wait(CThread *thread)
79 if (thread->handle == NULL)
81 return WaitObject(thread->handle);
84 WRes Thread_Close(CThread *thread)
86 return MyCloseHandle(&thread->handle);
89 WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
91 p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
92 return HandleToWRes(p->handle);
95 WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
97 return Event_Create(p, TRUE, initialSignaled);
99 WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
101 return ManualResetEvent_Create(p, 0);
104 WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
106 return Event_Create(p, FALSE, initialSignaled);
108 WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
110 return AutoResetEvent_Create(p, 0);
113 WRes Event_Set(CEvent *p)
115 return BOOLToWRes(SetEvent(p->handle));
117 WRes Event_Reset(CEvent *p)
119 return BOOLToWRes(ResetEvent(p->handle));
121 WRes Event_Wait(CEvent *p)
123 return WaitObject(p->handle);
125 WRes Event_Close(CEvent *p)
127 return MyCloseHandle(&p->handle);
130 WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
132 p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
133 return HandleToWRes(p->handle);
136 WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
138 return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
140 WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
142 return Semaphore_Release(p, (LONG)releaseCount, NULL);
144 WRes Semaphore_Release1(CSemaphore *p)
146 return Semaphore_ReleaseN(p, 1);
149 WRes Semaphore_Wait(CSemaphore *p)
151 return WaitObject(p->handle);
153 WRes Semaphore_Close(CSemaphore *p)
155 return MyCloseHandle(&p->handle);
158 WRes CriticalSection_Init(CCriticalSection *p)
161 /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
164 InitializeCriticalSection(p);
165 /* InitializeCriticalSectionAndSpinCount(p, 0); */
167 __except(EXCEPTION_EXECUTE_HANDLER)
172 InitializeCriticalSection(p);