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 #define _WIN32_WINNT 0x0400
16 #include "WinThreads.h"
17 #include "ThreadWorker.h"
19 IThreadWorker *WinThreader::MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded)
23 return new ThreadWorker(hooks, this, DEFAULT_THINK_TIME_MS);
25 return new BaseWorker(hooks);
29 void WinThreader::DestroyWorker(IThreadWorker *pWorker)
34 void WinThreader::ThreadSleep(unsigned int ms)
39 IMutex *WinThreader::MakeMutex()
41 WinMutex *pMutex = new WinMutex();
46 IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags)
48 ThreadParams defparams;
50 defparams.flags = flags;
51 defparams.prio = ThreadPrio_Normal;
53 return MakeThread(pThread, &defparams);
56 void WinThreader::MakeThread(IThread *pThread)
58 ThreadParams defparams;
60 defparams.flags = Thread_AutoRelease;
61 defparams.prio = ThreadPrio_Normal;
63 MakeThread(pThread, &defparams);
66 DWORD WINAPI Win32_ThreadGate(LPVOID param)
68 WinThreader::ThreadHandle *pHandle =
69 reinterpret_cast<WinThreader::ThreadHandle *>(param);
71 pHandle->m_run->RunThread(pHandle);
74 EnterCriticalSection(&pHandle->m_crit);
75 pHandle->m_state = Thread_Done;
76 pHandle->GetParams(¶ms);
77 LeaveCriticalSection(&pHandle->m_crit);
79 pHandle->m_run->OnTerminate(pHandle, false);
80 if (params.flags & Thread_AutoRelease)
86 void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
88 max = ThreadPrio_Maximum;
89 min = ThreadPrio_Minimum;
92 ThreadParams g_defparams;
93 IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params)
96 params = &g_defparams;
98 WinThreader::ThreadHandle *pHandle =
99 new WinThreader::ThreadHandle(this, NULL, pThread, params);
103 CreateThread(NULL, 0, &Win32_ThreadGate, (LPVOID)pHandle, CREATE_SUSPENDED, &tid);
105 if (!pHandle->m_thread)
111 if (pHandle->m_params.prio != ThreadPrio_Normal)
113 pHandle->SetPriority(pHandle->m_params.prio);
116 if (!(pHandle->m_params.flags & Thread_CreateSuspended))
124 IEventSignal *WinThreader::MakeEventSignal()
126 HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
131 WinEvent *pEvent = new WinEvent(event);
140 WinThreader::WinMutex::WinMutex()
142 InitializeCriticalSection(&m_crit);
145 WinThreader::WinMutex::~WinMutex()
147 DeleteCriticalSection(&m_crit);
150 bool WinThreader::WinMutex::TryLock()
152 return (TryEnterCriticalSection(&m_crit) != FALSE);
155 void WinThreader::WinMutex::Lock()
157 EnterCriticalSection(&m_crit);
160 void WinThreader::WinMutex::Unlock()
162 LeaveCriticalSection(&m_crit);
165 void WinThreader::WinMutex::DestroyThis()
174 WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params) :
175 m_parent(parent), m_thread(hthread), m_run(run), m_params(*params),
176 m_state(Thread_Paused)
178 InitializeCriticalSection(&m_crit);
181 WinThreader::ThreadHandle::~ThreadHandle()
185 CloseHandle(m_thread);
188 DeleteCriticalSection(&m_crit);
191 bool WinThreader::ThreadHandle::WaitForThread()
193 if (m_thread == NULL)
196 if (WaitForSingleObject(m_thread, INFINITE) != 0)
202 ThreadState WinThreader::ThreadHandle::GetState()
206 EnterCriticalSection(&m_crit);
208 LeaveCriticalSection(&m_crit);
213 IThreadCreator *WinThreader::ThreadHandle::Parent()
218 void WinThreader::ThreadHandle::DestroyThis()
220 if (m_params.flags & Thread_AutoRelease)
226 void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
231 *ptparams = m_params;
234 ThreadPriority WinThreader::ThreadHandle::GetPriority()
236 return m_params.prio;
239 bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio)
246 if (prio >= ThreadPrio_Maximum)
247 res = SetThreadPriority(m_thread, THREAD_PRIORITY_HIGHEST);
248 else if (prio <= ThreadPrio_Minimum)
249 res = SetThreadPriority(m_thread, THREAD_PRIORITY_LOWEST);
250 else if (prio == ThreadPrio_Normal)
251 res = SetThreadPriority(m_thread, THREAD_PRIORITY_NORMAL);
252 else if (prio == ThreadPrio_High)
253 res = SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
254 else if (prio == ThreadPrio_Low)
255 res = SetThreadPriority(m_thread, THREAD_PRIORITY_BELOW_NORMAL);
257 m_params.prio = prio;
259 return (res != FALSE);
262 bool WinThreader::ThreadHandle::Unpause()
267 if (m_state != Thread_Paused)
270 m_state = Thread_Running;
272 if (ResumeThread(m_thread) == -1)
274 m_state = Thread_Paused;
285 WinThreader::WinEvent::~WinEvent()
287 CloseHandle(m_event);
290 void WinThreader::WinEvent::Wait()
292 WaitForSingleObject(m_event, INFINITE);
295 void WinThreader::WinEvent::Signal()
300 void WinThreader::WinEvent::DestroyThis()