core/thread/BaseWorker.cpp
author David Anderson <dvander@alliedmods.net>
Thu Jul 12 16:57:26 2007 +0000 (2007-07-12)
changeset 1090 5c54e353c019
parent 1084 241c1b9b4048
child 1231 17badaf66ce4
permissions -rw-r--r--
- added callback functionality to IThreadWorker
- added exposure of IThreader to sample sdk
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     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
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include "BaseWorker.h"
    16 
    17 BaseWorker::BaseWorker(IThreadWorkerCallbacks *hooks) : 
    18 	m_perFrame(SM_DEFAULT_THREADS_PER_FRAME),
    19 	m_state(Worker_Stopped),
    20 	m_pHooks(hooks)
    21 {
    22 }
    23 
    24 BaseWorker::~BaseWorker()
    25 {
    26 	if (m_state != Worker_Stopped || m_state != Worker_Invalid)
    27 		Stop(true);
    28 
    29 	if (m_ThreadQueue.size())
    30 		Flush(true);
    31 }
    32 
    33 void BaseWorker::MakeThread(IThread *pThread)
    34 {
    35 	ThreadParams pt;
    36 
    37 	pt.flags = Thread_AutoRelease;
    38 	pt.prio = ThreadPrio_Normal;
    39 
    40 	MakeThread(pThread, &pt);
    41 }
    42 
    43 IThreadHandle *BaseWorker::MakeThread(IThread *pThread, ThreadFlags flags)
    44 {
    45 	ThreadParams pt;
    46 
    47 	pt.flags = flags;
    48 	pt.prio = ThreadPrio_Normal;
    49 
    50 	return MakeThread(pThread, &pt);
    51 }
    52 
    53 IThreadHandle *BaseWorker::MakeThread(IThread *pThread, const ThreadParams *params)
    54 {
    55 	if (m_state != Worker_Running)
    56 		return NULL;
    57 
    58 	SWThreadHandle *swt = new SWThreadHandle(this, params, pThread);
    59 
    60 	AddThreadToQueue(swt);
    61 
    62 	return swt;
    63 }
    64 
    65 void BaseWorker::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
    66 {
    67 	max = ThreadPrio_Normal;
    68 	min = ThreadPrio_Normal;
    69 }
    70 
    71 unsigned int BaseWorker::Flush(bool flush_cancel)
    72 {
    73 	SWThreadHandle *swt;
    74 	unsigned int num = 0;
    75 
    76 	while ((swt=PopThreadFromQueue()) != NULL)
    77 	{
    78 		swt->m_state = Thread_Done;
    79 		if (!flush_cancel)
    80 			swt->pThread->RunThread(swt);
    81 		swt->pThread->OnTerminate(swt, flush_cancel);
    82 		if (swt->m_params.flags & Thread_AutoRelease)
    83 			delete swt;
    84 		num++;
    85 	}
    86 
    87 	return num;
    88 }
    89 
    90 SWThreadHandle *BaseWorker::PopThreadFromQueue()
    91 {
    92 	if (!m_ThreadQueue.size())
    93 		return NULL;
    94 
    95 	SourceHook::List<SWThreadHandle *>::iterator begin;
    96 	SWThreadHandle *swt;
    97 
    98 	begin = m_ThreadQueue.begin();
    99 	swt = (*begin);
   100 	m_ThreadQueue.erase(begin);
   101 
   102 	return swt;
   103 }
   104 
   105 void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
   106 {
   107 	m_ThreadQueue.push_back(pHandle);
   108 }
   109 
   110 unsigned int BaseWorker::GetMaxThreadsPerFrame()
   111 {
   112 	return m_perFrame;
   113 }
   114 
   115 WorkerState BaseWorker::GetStatus(unsigned int *threads)
   116 {
   117 	if (threads)
   118 		*threads = m_perFrame;
   119 
   120 	return m_state;
   121 }
   122 
   123 unsigned int BaseWorker::RunFrame()
   124 {
   125 	unsigned int done = 0;
   126 	unsigned int max = GetMaxThreadsPerFrame();
   127 	SWThreadHandle *swt = NULL;
   128 	IThread *pThread = NULL;
   129 
   130 	while (done < max)
   131 	{
   132 		if ((swt=PopThreadFromQueue()) == NULL)
   133 		{
   134 			break;
   135 		}
   136 		pThread = swt->pThread;
   137 		swt->m_state = Thread_Running;
   138 		pThread->RunThread(swt);
   139 		swt->m_state = Thread_Done;
   140 		pThread->OnTerminate(swt, false);
   141 		if (swt->m_params.flags & Thread_AutoRelease)
   142 		{
   143 			delete swt;
   144 		}
   145 		done++;
   146 	}
   147 
   148 	return done;
   149 }
   150 
   151 void BaseWorker::SetMaxThreadsPerFrame(unsigned int threads)
   152 {
   153 	m_perFrame = threads;
   154 }
   155 
   156 bool BaseWorker::Start()
   157 {
   158 	if (m_state != Worker_Invalid && m_state != Worker_Stopped)
   159 	{
   160 		return false;
   161 	}
   162 
   163 	m_state = Worker_Running;
   164 
   165 	if (m_pHooks)
   166 	{
   167 		m_pHooks->OnWorkerStart(this);
   168 	}
   169 
   170     return true;
   171 }
   172 
   173 bool BaseWorker::Stop(bool flush_cancel)
   174 {
   175 	if (m_state == Worker_Invalid || m_state == Worker_Stopped)
   176 	{
   177 		return false;
   178 	}
   179 
   180 	if (m_state == Worker_Paused)
   181 	{
   182 		if (!Unpause())
   183 		{
   184 			return false;
   185 		}
   186 	}
   187 
   188 	m_state = Worker_Stopped;
   189 	Flush(flush_cancel);
   190 
   191 	if (m_pHooks)
   192 	{
   193 		m_pHooks->OnWorkerStop(this);
   194 	}
   195 
   196 	return true;
   197 }
   198 
   199 bool BaseWorker::Pause()
   200 {
   201 	if (m_state != Worker_Running)
   202 	{
   203 		return false;
   204 	}
   205 
   206 	m_state = Worker_Paused;
   207 
   208 	return true;
   209 }
   210 
   211 
   212 bool BaseWorker::Unpause()
   213 {
   214 	if (m_state != Worker_Paused)
   215 	{
   216 		return false;
   217 	}
   218 
   219 	m_state = Worker_Running;
   220 
   221 	return true;
   222 }
   223 
   224 /***********************
   225  * THREAD HANDLE STUFF *
   226  ***********************/
   227 
   228 void SWThreadHandle::DestroyThis()
   229 {
   230 	delete this;
   231 }
   232 
   233 void SWThreadHandle::GetParams(ThreadParams *p)
   234 {
   235 	*p = m_params;
   236 }
   237 
   238 ThreadPriority SWThreadHandle::GetPriority()
   239 {
   240 	return m_params.prio;
   241 }
   242 
   243 ThreadState SWThreadHandle::GetState()
   244 {
   245 	return m_state;
   246 }
   247 
   248 IThreadCreator *SWThreadHandle::Parent()
   249 {
   250 	return m_parent;
   251 }
   252 
   253 bool SWThreadHandle::SetPriority(ThreadPriority prio)
   254 {
   255 	if (m_params.prio != ThreadPrio_Normal)
   256 		return false;
   257 
   258 	m_params.prio = prio;
   259 
   260 	return true;
   261 }
   262 
   263 bool SWThreadHandle::Unpause()
   264 {
   265 	if (m_state != Thread_Paused)
   266 		return false;
   267 
   268 	m_state = Thread_Running;
   269 
   270 	return true;
   271 }
   272 
   273 bool SWThreadHandle::WaitForThread()
   274 {
   275 	return false;
   276 }
   277 
   278 SWThreadHandle::SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread) : 
   279 	m_state(Thread_Paused), m_params(*p), m_parent(parent), pThread(thread)
   280 {
   281 }
   282 
   283 IThread *SWThreadHandle::GetThread()
   284 {
   285 	return pThread;
   286 }