1.1 --- a/core/thread/WinThreads.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,320 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#define _WIN32_WINNT 0x0400
1.36 -#include "WinThreads.h"
1.37 -#include "ThreadWorker.h"
1.38 -
1.39 -IThreadWorker *WinThreader::MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded)
1.40 -{
1.41 - if (threaded)
1.42 - {
1.43 - return new ThreadWorker(hooks, this, DEFAULT_THINK_TIME_MS);
1.44 - } else {
1.45 - return new BaseWorker(hooks);
1.46 - }
1.47 -}
1.48 -
1.49 -void WinThreader::DestroyWorker(IThreadWorker *pWorker)
1.50 -{
1.51 - delete pWorker;
1.52 -}
1.53 -
1.54 -void WinThreader::ThreadSleep(unsigned int ms)
1.55 -{
1.56 - Sleep((DWORD)ms);
1.57 -}
1.58 -
1.59 -IMutex *WinThreader::MakeMutex()
1.60 -{
1.61 - WinMutex *pMutex = new WinMutex();
1.62 -
1.63 - return pMutex;
1.64 -}
1.65 -
1.66 -IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags)
1.67 -{
1.68 - ThreadParams defparams;
1.69 -
1.70 - defparams.flags = flags;
1.71 - defparams.prio = ThreadPrio_Normal;
1.72 -
1.73 - return MakeThread(pThread, &defparams);
1.74 -}
1.75 -
1.76 -void WinThreader::MakeThread(IThread *pThread)
1.77 -{
1.78 - ThreadParams defparams;
1.79 -
1.80 - defparams.flags = Thread_AutoRelease;
1.81 - defparams.prio = ThreadPrio_Normal;
1.82 -
1.83 - MakeThread(pThread, &defparams);
1.84 -}
1.85 -
1.86 -DWORD WINAPI Win32_ThreadGate(LPVOID param)
1.87 -{
1.88 - WinThreader::ThreadHandle *pHandle =
1.89 - reinterpret_cast<WinThreader::ThreadHandle *>(param);
1.90 -
1.91 - pHandle->m_run->RunThread(pHandle);
1.92 -
1.93 - ThreadParams params;
1.94 - EnterCriticalSection(&pHandle->m_crit);
1.95 - pHandle->m_state = Thread_Done;
1.96 - pHandle->GetParams(¶ms);
1.97 - LeaveCriticalSection(&pHandle->m_crit);
1.98 -
1.99 - pHandle->m_run->OnTerminate(pHandle, false);
1.100 - if (params.flags & Thread_AutoRelease)
1.101 - delete pHandle;
1.102 -
1.103 - return 0;
1.104 -}
1.105 -
1.106 -void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
1.107 -{
1.108 - max = ThreadPrio_Maximum;
1.109 - min = ThreadPrio_Minimum;
1.110 -}
1.111 -
1.112 -ThreadParams g_defparams;
1.113 -IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params)
1.114 -{
1.115 - if (params == NULL)
1.116 - params = &g_defparams;
1.117 -
1.118 - WinThreader::ThreadHandle *pHandle =
1.119 - new WinThreader::ThreadHandle(this, NULL, pThread, params);
1.120 -
1.121 - DWORD tid;
1.122 - pHandle->m_thread =
1.123 - CreateThread(NULL, 0, &Win32_ThreadGate, (LPVOID)pHandle, CREATE_SUSPENDED, &tid);
1.124 -
1.125 - if (!pHandle->m_thread)
1.126 - {
1.127 - delete pHandle;
1.128 - return NULL;
1.129 - }
1.130 -
1.131 - if (pHandle->m_params.prio != ThreadPrio_Normal)
1.132 - {
1.133 - pHandle->SetPriority(pHandle->m_params.prio);
1.134 - }
1.135 -
1.136 - if (!(pHandle->m_params.flags & Thread_CreateSuspended))
1.137 - {
1.138 - pHandle->Unpause();
1.139 - }
1.140 -
1.141 - return pHandle;
1.142 -}
1.143 -
1.144 -IEventSignal *WinThreader::MakeEventSignal()
1.145 -{
1.146 - HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
1.147 -
1.148 - if (!event)
1.149 - return NULL;
1.150 -
1.151 - WinEvent *pEvent = new WinEvent(event);
1.152 -
1.153 - return pEvent;
1.154 -}
1.155 -
1.156 -/*****************
1.157 - **** Mutexes ****
1.158 - *****************/
1.159 -
1.160 -WinThreader::WinMutex::WinMutex()
1.161 -{
1.162 - InitializeCriticalSection(&m_crit);
1.163 -}
1.164 -
1.165 -WinThreader::WinMutex::~WinMutex()
1.166 -{
1.167 - DeleteCriticalSection(&m_crit);
1.168 -}
1.169 -
1.170 -bool WinThreader::WinMutex::TryLock()
1.171 -{
1.172 - return (TryEnterCriticalSection(&m_crit) != FALSE);
1.173 -}
1.174 -
1.175 -void WinThreader::WinMutex::Lock()
1.176 -{
1.177 - EnterCriticalSection(&m_crit);
1.178 -}
1.179 -
1.180 -void WinThreader::WinMutex::Unlock()
1.181 -{
1.182 - LeaveCriticalSection(&m_crit);
1.183 -}
1.184 -
1.185 -void WinThreader::WinMutex::DestroyThis()
1.186 -{
1.187 - delete this;
1.188 -}
1.189 -
1.190 -/******************
1.191 - * Thread Handles *
1.192 - ******************/
1.193 -
1.194 -WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params) :
1.195 - m_parent(parent), m_thread(hthread), m_run(run), m_params(*params),
1.196 - m_state(Thread_Paused)
1.197 -{
1.198 - InitializeCriticalSection(&m_crit);
1.199 -}
1.200 -
1.201 -WinThreader::ThreadHandle::~ThreadHandle()
1.202 -{
1.203 - if (m_thread)
1.204 - {
1.205 - CloseHandle(m_thread);
1.206 - m_thread = NULL;
1.207 - }
1.208 - DeleteCriticalSection(&m_crit);
1.209 -}
1.210 -
1.211 -bool WinThreader::ThreadHandle::WaitForThread()
1.212 -{
1.213 - if (m_thread == NULL)
1.214 - return false;
1.215 -
1.216 - if (WaitForSingleObject(m_thread, INFINITE) != 0)
1.217 - return false;
1.218 -
1.219 - return true;
1.220 -}
1.221 -
1.222 -ThreadState WinThreader::ThreadHandle::GetState()
1.223 -{
1.224 - ThreadState state;
1.225 -
1.226 - EnterCriticalSection(&m_crit);
1.227 - state = m_state;
1.228 - LeaveCriticalSection(&m_crit);
1.229 -
1.230 - return state;
1.231 -}
1.232 -
1.233 -IThreadCreator *WinThreader::ThreadHandle::Parent()
1.234 -{
1.235 - return m_parent;
1.236 -}
1.237 -
1.238 -void WinThreader::ThreadHandle::DestroyThis()
1.239 -{
1.240 - if (m_params.flags & Thread_AutoRelease)
1.241 - return;
1.242 -
1.243 - delete this;
1.244 -}
1.245 -
1.246 -void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
1.247 -{
1.248 - if (!ptparams)
1.249 - return;
1.250 -
1.251 - *ptparams = m_params;
1.252 -}
1.253 -
1.254 -ThreadPriority WinThreader::ThreadHandle::GetPriority()
1.255 -{
1.256 - return m_params.prio;
1.257 -}
1.258 -
1.259 -bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio)
1.260 -{
1.261 - if (!m_thread)
1.262 - return false;
1.263 -
1.264 - BOOL res = FALSE;
1.265 -
1.266 - if (prio >= ThreadPrio_Maximum)
1.267 - res = SetThreadPriority(m_thread, THREAD_PRIORITY_HIGHEST);
1.268 - else if (prio <= ThreadPrio_Minimum)
1.269 - res = SetThreadPriority(m_thread, THREAD_PRIORITY_LOWEST);
1.270 - else if (prio == ThreadPrio_Normal)
1.271 - res = SetThreadPriority(m_thread, THREAD_PRIORITY_NORMAL);
1.272 - else if (prio == ThreadPrio_High)
1.273 - res = SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
1.274 - else if (prio == ThreadPrio_Low)
1.275 - res = SetThreadPriority(m_thread, THREAD_PRIORITY_BELOW_NORMAL);
1.276 -
1.277 - m_params.prio = prio;
1.278 -
1.279 - return (res != FALSE);
1.280 -}
1.281 -
1.282 -bool WinThreader::ThreadHandle::Unpause()
1.283 -{
1.284 - if (!m_thread)
1.285 - return false;
1.286 -
1.287 - if (m_state != Thread_Paused)
1.288 - return false;
1.289 -
1.290 - m_state = Thread_Running;
1.291 -
1.292 - if (ResumeThread(m_thread) == -1)
1.293 - {
1.294 - m_state = Thread_Paused;
1.295 - return false;
1.296 - }
1.297 -
1.298 - return true;
1.299 -}
1.300 -
1.301 -/*****************
1.302 - * EVENT SIGNALS *
1.303 - *****************/
1.304 -
1.305 -WinThreader::WinEvent::~WinEvent()
1.306 -{
1.307 - CloseHandle(m_event);
1.308 -}
1.309 -
1.310 -void WinThreader::WinEvent::Wait()
1.311 -{
1.312 - WaitForSingleObject(m_event, INFINITE);
1.313 -}
1.314 -
1.315 -void WinThreader::WinEvent::Signal()
1.316 -{
1.317 - SetEvent(m_event);
1.318 -}
1.319 -
1.320 -void WinThreader::WinEvent::DestroyThis()
1.321 -{
1.322 - delete this;
1.323 -}