core/logic/thread/WinThreads.cpp
author Ruben Gonzalez <drifter01620@gmail.com>
Thu May 22 09:49:27 2014 -0400 (2014-05-22)
changeset 4378 568f4497ef4a
parent 4025 542dde661d5c
permissions -rw-r--r--
Update CS:GO team score gamedata.
     1 /**
     2  * vim: set ts=4 sw=4 tw=99 noet:
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #define _WIN32_WINNT 0x0400
    33 #include "WinThreads.h"
    34 #include "ThreadWorker.h"
    35 
    36 IThreadWorker *WinThreader::MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded)
    37 {
    38 	if (threaded)
    39 	{
    40 		return new ThreadWorker(hooks, this, DEFAULT_THINK_TIME_MS);
    41 	} else {
    42 		return new BaseWorker(hooks);
    43 	}
    44 }
    45 
    46 void WinThreader::DestroyWorker(IThreadWorker *pWorker)
    47 {
    48 	delete pWorker;
    49 }
    50 
    51 void WinThreader::ThreadSleep(unsigned int ms)
    52 {
    53 	Sleep((DWORD)ms);
    54 }
    55 
    56 IMutex *WinThreader::MakeMutex()
    57 {
    58 	return new CompatMutex();
    59 }
    60 
    61 IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags)
    62 {
    63 	ThreadParams defparams;
    64 
    65 	defparams.flags = flags;
    66 	defparams.prio = ThreadPrio_Normal;
    67 
    68 	return MakeThread(pThread, &defparams);
    69 }
    70 
    71 void WinThreader::MakeThread(IThread *pThread)
    72 {
    73 	ThreadParams defparams;
    74 
    75 	defparams.flags = Thread_AutoRelease;
    76 	defparams.prio = ThreadPrio_Normal;
    77 
    78 	MakeThread(pThread, &defparams);
    79 }
    80 
    81 void WinThreader::ThreadHandle::Run()
    82 {
    83 	// Wait for an unpause if necessary.
    84 	{
    85 		ke::AutoLock lock(&suspend_);
    86 		if (m_state == Thread_Paused)
    87 			suspend_.Wait();
    88 	}
    89 	
    90 	m_run->RunThread(this);
    91 	m_state = Thread_Done;
    92 	m_run->OnTerminate(this, false);
    93 	if (m_params.flags & Thread_AutoRelease)
    94 		delete this;
    95 }
    96 
    97 void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
    98 {
    99 	max = ThreadPrio_Maximum;
   100 	min = ThreadPrio_Minimum;
   101 }
   102 
   103 ThreadParams g_defparams;
   104 IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params)
   105 {
   106 	if (params == NULL)
   107 		params = &g_defparams;
   108 
   109 	ke::AutoPtr<ThreadHandle> pHandle(new ThreadHandle(this, pThread, params));
   110 
   111 	pHandle->m_thread = new ke::Thread(pHandle, "SourceMod");
   112 	if (!pHandle->m_thread->Succeeded())
   113 		return NULL;
   114 
   115 	if (pHandle->m_params.prio != ThreadPrio_Normal)
   116 		pHandle->SetPriority(pHandle->m_params.prio);
   117 
   118 	if (!(params->flags & Thread_CreateSuspended))
   119 		pHandle->Unpause();
   120 
   121 	return pHandle.take();
   122 }
   123 
   124 IEventSignal *WinThreader::MakeEventSignal()
   125 {
   126 	return new CompatCondVar();
   127 }
   128 
   129 /******************
   130  * Thread Handles *
   131  ******************/
   132 
   133 WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params) : 
   134 	m_parent(parent), m_run(run), m_params(*params),
   135 	m_state(Thread_Paused)
   136 {
   137 }
   138 
   139 WinThreader::ThreadHandle::~ThreadHandle()
   140 {
   141 }
   142 
   143 bool WinThreader::ThreadHandle::WaitForThread()
   144 {
   145 	if (!m_thread)
   146 		return false;
   147 
   148 	m_thread->Join();
   149 	return true;
   150 }
   151 
   152 ThreadState WinThreader::ThreadHandle::GetState()
   153 {
   154 	return m_state;
   155 }
   156 
   157 IThreadCreator *WinThreader::ThreadHandle::Parent()
   158 {
   159 	return m_parent;
   160 }
   161 
   162 void WinThreader::ThreadHandle::DestroyThis()
   163 {
   164 	if (m_params.flags & Thread_AutoRelease)
   165 		return;
   166 
   167 	delete this;
   168 }
   169 
   170 void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
   171 {
   172 	if (!ptparams)
   173 		return;
   174 
   175 	*ptparams = m_params;
   176 }
   177 
   178 ThreadPriority WinThreader::ThreadHandle::GetPriority()
   179 {
   180 	return m_params.prio;
   181 }
   182 
   183 bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio)
   184 {
   185 	BOOL res = FALSE;
   186 
   187 	if (prio >= ThreadPrio_Maximum)
   188 		res = SetThreadPriority(m_thread->handle(), THREAD_PRIORITY_HIGHEST);
   189 	else if (prio <= ThreadPrio_Minimum)
   190 		res = SetThreadPriority(m_thread->handle(), THREAD_PRIORITY_LOWEST);
   191 	else if (prio == ThreadPrio_Normal)
   192 		res = SetThreadPriority(m_thread->handle(), THREAD_PRIORITY_NORMAL);
   193 	else if (prio == ThreadPrio_High)
   194 		res = SetThreadPriority(m_thread->handle(), THREAD_PRIORITY_ABOVE_NORMAL);
   195 	else if (prio == ThreadPrio_Low)
   196 		res = SetThreadPriority(m_thread->handle(), THREAD_PRIORITY_BELOW_NORMAL);
   197 
   198 	m_params.prio = prio;
   199 
   200 	return (res != FALSE);
   201 }
   202 
   203 bool WinThreader::ThreadHandle::Unpause()
   204 {
   205 	if (m_state != Thread_Paused)
   206 		return false;
   207 
   208 	ke::AutoLock lock(&suspend_);
   209 	m_state = Thread_Running;
   210 	suspend_.Notify();
   211 	return true;
   212 }