3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
15 #include "WinThreads.h"
16 #include "ThreadWorker.h"
18 IThreadWorker *WinThreader::MakeWorker(bool threaded)
22 return new ThreadWorker(this, DEFAULT_THINK_TIME_MS);
24 return new BaseWorker();
28 void WinThreader::DestroyWorker(IThreadWorker *pWorker)
33 void WinThreader::ThreadSleep(unsigned int ms)
38 IMutex *WinThreader::MakeMutex()
40 HANDLE mutex = CreateMutexA(NULL, FALSE, NULL);
45 WinMutex *pMutex = new WinMutex(mutex);
50 IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags)
52 ThreadParams defparams;
54 defparams.flags = flags;
55 defparams.prio = ThreadPrio_Normal;
57 return MakeThread(pThread, &defparams);
60 void WinThreader::MakeThread(IThread *pThread)
62 ThreadParams defparams;
64 defparams.flags = Thread_AutoRelease;
65 defparams.prio = ThreadPrio_Normal;
67 MakeThread(pThread, &defparams);
70 DWORD WINAPI Win32_ThreadGate(LPVOID param)
72 WinThreader::ThreadHandle *pHandle =
73 reinterpret_cast<WinThreader::ThreadHandle *>(param);
75 pHandle->m_run->RunThread(pHandle);
78 EnterCriticalSection(&pHandle->m_crit);
79 pHandle->m_state = Thread_Done;
80 pHandle->GetParams(¶ms);
81 LeaveCriticalSection(&pHandle->m_crit);
83 pHandle->m_run->OnTerminate(pHandle, false);
84 if (params.flags & Thread_AutoRelease)
90 void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
92 max = ThreadPrio_Maximum;
93 min = ThreadPrio_Minimum;
96 ThreadParams g_defparams;
97 IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params)
100 params = &g_defparams;
102 WinThreader::ThreadHandle *pHandle =
103 new WinThreader::ThreadHandle(this, NULL, pThread, params);
107 CreateThread(NULL, 0, &Win32_ThreadGate, (LPVOID)pHandle, CREATE_SUSPENDED, &tid);
109 if (!pHandle->m_thread)
115 if (pHandle->m_params.prio != ThreadPrio_Normal)
117 pHandle->SetPriority(pHandle->m_params.prio);
120 if (!(pHandle->m_params.flags & Thread_CreateSuspended))
128 IEventSignal *WinThreader::MakeEventSignal()
130 HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
135 WinEvent *pEvent = new WinEvent(event);
144 WinThreader::WinMutex::~WinMutex()
148 CloseHandle(m_mutex);
153 bool WinThreader::WinMutex::TryLock()
158 if (WaitForSingleObject(m_mutex, 0) != WAIT_FAILED)
164 void WinThreader::WinMutex::Lock()
169 WaitForSingleObject(m_mutex, INFINITE);
172 void WinThreader::WinMutex::Unlock()
177 ReleaseMutex(m_mutex);
180 void WinThreader::WinMutex::DestroyThis()
189 WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params) :
190 m_parent(parent), m_thread(hthread), m_run(run), m_params(*params),
191 m_state(Thread_Paused)
193 InitializeCriticalSection(&m_crit);
196 WinThreader::ThreadHandle::~ThreadHandle()
200 CloseHandle(m_thread);
203 DeleteCriticalSection(&m_crit);
206 bool WinThreader::ThreadHandle::WaitForThread()
208 if (m_thread == NULL)
211 if (WaitForSingleObject(m_thread, INFINITE) != 0)
217 ThreadState WinThreader::ThreadHandle::GetState()
221 EnterCriticalSection(&m_crit);
223 LeaveCriticalSection(&m_crit);
228 IThreadCreator *WinThreader::ThreadHandle::Parent()
233 void WinThreader::ThreadHandle::DestroyThis()
235 if (m_params.flags & Thread_AutoRelease)
241 void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
246 *ptparams = m_params;
249 ThreadPriority WinThreader::ThreadHandle::GetPriority()
251 return m_params.prio;
254 bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio)
261 if (prio >= ThreadPrio_Maximum)
262 res = SetThreadPriority(m_thread, THREAD_PRIORITY_HIGHEST);
263 else if (prio <= ThreadPrio_Minimum)
264 res = SetThreadPriority(m_thread, THREAD_PRIORITY_LOWEST);
265 else if (prio == ThreadPrio_Normal)
266 res = SetThreadPriority(m_thread, THREAD_PRIORITY_NORMAL);
267 else if (prio == ThreadPrio_High)
268 res = SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
269 else if (prio == ThreadPrio_Low)
270 res = SetThreadPriority(m_thread, THREAD_PRIORITY_BELOW_NORMAL);
272 m_params.prio = prio;
274 return (res != FALSE);
277 bool WinThreader::ThreadHandle::Unpause()
282 if (m_state != Thread_Paused)
285 m_state = Thread_Running;
287 if (ResumeThread(m_thread) == -1)
289 m_state = Thread_Paused;
300 WinThreader::WinEvent::~WinEvent()
302 CloseHandle(m_event);
305 void WinThreader::WinEvent::Wait()
307 WaitForSingleObject(m_event, INFINITE);
310 void WinThreader::WinEvent::Signal()
315 void WinThreader::WinEvent::DestroyThis()