3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
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.
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
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/>.
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>.
32 #include "BaseWorker.h"
34 BaseWorker::BaseWorker(IThreadWorkerCallbacks *hooks) :
35 m_perFrame(SM_DEFAULT_THREADS_PER_FRAME),
36 m_state(Worker_Stopped),
41 BaseWorker::~BaseWorker()
43 if (m_state != Worker_Stopped || m_state != Worker_Invalid)
46 if (m_ThreadQueue.size())
50 void BaseWorker::MakeThread(IThread *pThread)
54 pt.flags = Thread_AutoRelease;
55 pt.prio = ThreadPrio_Normal;
57 MakeThread(pThread, &pt);
60 IThreadHandle *BaseWorker::MakeThread(IThread *pThread, ThreadFlags flags)
65 pt.prio = ThreadPrio_Normal;
67 return MakeThread(pThread, &pt);
70 IThreadHandle *BaseWorker::MakeThread(IThread *pThread, const ThreadParams *params)
72 if (m_state != Worker_Running)
75 SWThreadHandle *swt = new SWThreadHandle(this, params, pThread);
77 AddThreadToQueue(swt);
82 void BaseWorker::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
84 max = ThreadPrio_Normal;
85 min = ThreadPrio_Normal;
88 unsigned int BaseWorker::Flush(bool flush_cancel)
93 while ((swt=PopThreadFromQueue()) != NULL)
95 swt->m_state = Thread_Done;
97 swt->pThread->RunThread(swt);
98 swt->pThread->OnTerminate(swt, flush_cancel);
99 if (swt->m_params.flags & Thread_AutoRelease)
107 SWThreadHandle *BaseWorker::PopThreadFromQueue()
109 if (!m_ThreadQueue.size())
112 SourceHook::List<SWThreadHandle *>::iterator begin;
115 begin = m_ThreadQueue.begin();
117 m_ThreadQueue.erase(begin);
122 void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
124 m_ThreadQueue.push_back(pHandle);
127 unsigned int BaseWorker::GetMaxThreadsPerFrame()
132 WorkerState BaseWorker::GetStatus(unsigned int *threads)
135 *threads = m_perFrame;
140 unsigned int BaseWorker::RunFrame()
142 unsigned int done = 0;
143 unsigned int max = GetMaxThreadsPerFrame();
144 SWThreadHandle *swt = NULL;
145 IThread *pThread = NULL;
149 if ((swt=PopThreadFromQueue()) == NULL)
153 pThread = swt->pThread;
154 swt->m_state = Thread_Running;
155 pThread->RunThread(swt);
156 swt->m_state = Thread_Done;
157 pThread->OnTerminate(swt, false);
158 if (swt->m_params.flags & Thread_AutoRelease)
168 void BaseWorker::SetMaxThreadsPerFrame(unsigned int threads)
170 m_perFrame = threads;
173 bool BaseWorker::Start()
175 if (m_state != Worker_Invalid && m_state != Worker_Stopped)
180 m_state = Worker_Running;
184 m_pHooks->OnWorkerStart(this);
190 bool BaseWorker::Stop(bool flush_cancel)
192 if (m_state == Worker_Invalid || m_state == Worker_Stopped)
197 if (m_state == Worker_Paused)
205 m_state = Worker_Stopped;
210 m_pHooks->OnWorkerStop(this);
216 bool BaseWorker::Pause()
218 if (m_state != Worker_Running)
223 m_state = Worker_Paused;
229 bool BaseWorker::Unpause()
231 if (m_state != Worker_Paused)
236 m_state = Worker_Running;
241 /***********************
242 * THREAD HANDLE STUFF *
243 ***********************/
245 void SWThreadHandle::DestroyThis()
250 void SWThreadHandle::GetParams(ThreadParams *p)
255 ThreadPriority SWThreadHandle::GetPriority()
257 return m_params.prio;
260 ThreadState SWThreadHandle::GetState()
265 IThreadCreator *SWThreadHandle::Parent()
270 bool SWThreadHandle::SetPriority(ThreadPriority prio)
272 if (m_params.prio != ThreadPrio_Normal)
275 m_params.prio = prio;
280 bool SWThreadHandle::Unpause()
282 if (m_state != Thread_Paused)
285 m_state = Thread_Running;
290 bool SWThreadHandle::WaitForThread()
295 SWThreadHandle::SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread) :
296 m_state(Thread_Paused), m_params(*p), m_parent(parent), pThread(thread)
300 IThread *SWThreadHandle::GetThread()