diff -r 7602d7fb60d9 -r 026da5437111 core/thread/WinThreads.cpp --- a/core/thread/WinThreads.cpp Fri Jul 11 06:51:21 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,320 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#define _WIN32_WINNT 0x0400 -#include "WinThreads.h" -#include "ThreadWorker.h" - -IThreadWorker *WinThreader::MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded) -{ - if (threaded) - { - return new ThreadWorker(hooks, this, DEFAULT_THINK_TIME_MS); - } else { - return new BaseWorker(hooks); - } -} - -void WinThreader::DestroyWorker(IThreadWorker *pWorker) -{ - delete pWorker; -} - -void WinThreader::ThreadSleep(unsigned int ms) -{ - Sleep((DWORD)ms); -} - -IMutex *WinThreader::MakeMutex() -{ - WinMutex *pMutex = new WinMutex(); - - return pMutex; -} - -IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags) -{ - ThreadParams defparams; - - defparams.flags = flags; - defparams.prio = ThreadPrio_Normal; - - return MakeThread(pThread, &defparams); -} - -void WinThreader::MakeThread(IThread *pThread) -{ - ThreadParams defparams; - - defparams.flags = Thread_AutoRelease; - defparams.prio = ThreadPrio_Normal; - - MakeThread(pThread, &defparams); -} - -DWORD WINAPI Win32_ThreadGate(LPVOID param) -{ - WinThreader::ThreadHandle *pHandle = - reinterpret_cast(param); - - pHandle->m_run->RunThread(pHandle); - - ThreadParams params; - EnterCriticalSection(&pHandle->m_crit); - pHandle->m_state = Thread_Done; - pHandle->GetParams(¶ms); - LeaveCriticalSection(&pHandle->m_crit); - - pHandle->m_run->OnTerminate(pHandle, false); - if (params.flags & Thread_AutoRelease) - delete pHandle; - - return 0; -} - -void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) -{ - max = ThreadPrio_Maximum; - min = ThreadPrio_Minimum; -} - -ThreadParams g_defparams; -IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params) -{ - if (params == NULL) - params = &g_defparams; - - WinThreader::ThreadHandle *pHandle = - new WinThreader::ThreadHandle(this, NULL, pThread, params); - - DWORD tid; - pHandle->m_thread = - CreateThread(NULL, 0, &Win32_ThreadGate, (LPVOID)pHandle, CREATE_SUSPENDED, &tid); - - if (!pHandle->m_thread) - { - delete pHandle; - return NULL; - } - - if (pHandle->m_params.prio != ThreadPrio_Normal) - { - pHandle->SetPriority(pHandle->m_params.prio); - } - - if (!(pHandle->m_params.flags & Thread_CreateSuspended)) - { - pHandle->Unpause(); - } - - return pHandle; -} - -IEventSignal *WinThreader::MakeEventSignal() -{ - HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); - - if (!event) - return NULL; - - WinEvent *pEvent = new WinEvent(event); - - return pEvent; -} - -/***************** - **** Mutexes **** - *****************/ - -WinThreader::WinMutex::WinMutex() -{ - InitializeCriticalSection(&m_crit); -} - -WinThreader::WinMutex::~WinMutex() -{ - DeleteCriticalSection(&m_crit); -} - -bool WinThreader::WinMutex::TryLock() -{ - return (TryEnterCriticalSection(&m_crit) != FALSE); -} - -void WinThreader::WinMutex::Lock() -{ - EnterCriticalSection(&m_crit); -} - -void WinThreader::WinMutex::Unlock() -{ - LeaveCriticalSection(&m_crit); -} - -void WinThreader::WinMutex::DestroyThis() -{ - delete this; -} - -/****************** - * Thread Handles * - ******************/ - -WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params) : - m_parent(parent), m_thread(hthread), m_run(run), m_params(*params), - m_state(Thread_Paused) -{ - InitializeCriticalSection(&m_crit); -} - -WinThreader::ThreadHandle::~ThreadHandle() -{ - if (m_thread) - { - CloseHandle(m_thread); - m_thread = NULL; - } - DeleteCriticalSection(&m_crit); -} - -bool WinThreader::ThreadHandle::WaitForThread() -{ - if (m_thread == NULL) - return false; - - if (WaitForSingleObject(m_thread, INFINITE) != 0) - return false; - - return true; -} - -ThreadState WinThreader::ThreadHandle::GetState() -{ - ThreadState state; - - EnterCriticalSection(&m_crit); - state = m_state; - LeaveCriticalSection(&m_crit); - - return state; -} - -IThreadCreator *WinThreader::ThreadHandle::Parent() -{ - return m_parent; -} - -void WinThreader::ThreadHandle::DestroyThis() -{ - if (m_params.flags & Thread_AutoRelease) - return; - - delete this; -} - -void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams) -{ - if (!ptparams) - return; - - *ptparams = m_params; -} - -ThreadPriority WinThreader::ThreadHandle::GetPriority() -{ - return m_params.prio; -} - -bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio) -{ - if (!m_thread) - return false; - - BOOL res = FALSE; - - if (prio >= ThreadPrio_Maximum) - res = SetThreadPriority(m_thread, THREAD_PRIORITY_HIGHEST); - else if (prio <= ThreadPrio_Minimum) - res = SetThreadPriority(m_thread, THREAD_PRIORITY_LOWEST); - else if (prio == ThreadPrio_Normal) - res = SetThreadPriority(m_thread, THREAD_PRIORITY_NORMAL); - else if (prio == ThreadPrio_High) - res = SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL); - else if (prio == ThreadPrio_Low) - res = SetThreadPriority(m_thread, THREAD_PRIORITY_BELOW_NORMAL); - - m_params.prio = prio; - - return (res != FALSE); -} - -bool WinThreader::ThreadHandle::Unpause() -{ - if (!m_thread) - return false; - - if (m_state != Thread_Paused) - return false; - - m_state = Thread_Running; - - if (ResumeThread(m_thread) == -1) - { - m_state = Thread_Paused; - return false; - } - - return true; -} - -/***************** - * EVENT SIGNALS * - *****************/ - -WinThreader::WinEvent::~WinEvent() -{ - CloseHandle(m_event); -} - -void WinThreader::WinEvent::Wait() -{ - WaitForSingleObject(m_event, INFINITE); -} - -void WinThreader::WinEvent::Signal() -{ - SetEvent(m_event); -} - -void WinThreader::WinEvent::DestroyThis() -{ - delete this; -}