diff -r c7b4237fff50 -r 03a67e41afbc core/thread/ThreadWorker.cpp
--- a/core/thread/ThreadWorker.cpp Fri Mar 28 06:21:34 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-/**
- * vim: set ts=4 :
- * =============================================================================
- * SourceMod
- * Copyright (C) 2004-2007 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$
- */
-
-#include "ThreadWorker.h"
-
-ThreadWorker::ThreadWorker(IThreadWorkerCallbacks *hooks) : BaseWorker(hooks),
- m_Threader(NULL),
- m_QueueLock(NULL),
- m_StateLock(NULL),
- m_PauseSignal(NULL),
- m_AddSignal(NULL),
- me(NULL),
- m_think_time(DEFAULT_THINK_TIME_MS)
-{
- m_state = Worker_Invalid;
-}
-
-ThreadWorker::ThreadWorker(IThreadWorkerCallbacks *hooks, IThreader *pThreader, unsigned int thinktime) :
- BaseWorker(hooks),
- m_Threader(pThreader),
- m_QueueLock(NULL),
- m_StateLock(NULL),
- m_PauseSignal(NULL),
- m_AddSignal(NULL),
- me(NULL),
- m_think_time(thinktime)
-{
- if (m_Threader)
- {
- m_state = Worker_Stopped;
- } else {
- m_state = Worker_Invalid;
- }
-}
-
-ThreadWorker::~ThreadWorker()
-{
- if (m_state != Worker_Stopped || m_state != Worker_Invalid)
- {
- Stop(true);
- }
-
- if (m_ThreadQueue.size())
- {
- Flush(true);
- }
-}
-
-void ThreadWorker::OnTerminate(IThreadHandle *pHandle, bool cancel)
-{
- //we don't particularly care
- return;
-}
-
-void ThreadWorker::RunThread(IThreadHandle *pHandle)
-{
- WorkerState this_state = Worker_Running;
- size_t num;
-
- if (m_pHooks)
- {
- m_pHooks->OnWorkerStart(this);
- }
-
- while (true)
- {
- /**
- * Check number of items in the queue
- */
- m_StateLock->Lock();
- this_state = m_state;
- m_StateLock->Unlock();
- if (this_state != Worker_Stopped)
- {
- m_QueueLock->Lock();
- num = m_ThreadQueue.size();
- if (!num)
- {
- /**
- * if none, wait for an item
- */
- m_Waiting = true;
- m_QueueLock->Unlock();
- /* first check if we should end again */
- if (this_state == Worker_Stopped)
- {
- break;
- }
- m_AddSignal->Wait();
- m_Waiting = false;
- } else {
- m_QueueLock->Unlock();
- }
- }
- m_StateLock->Lock();
- this_state = m_state;
- m_StateLock->Unlock();
- if (this_state != Worker_Running)
- {
- if (this_state == Worker_Paused || this_state == Worker_Stopped)
- {
- //wait until the lock is cleared.
- if (this_state == Worker_Paused)
- {
- m_PauseSignal->Wait();
- }
- if (this_state == Worker_Stopped)
- {
- //if we're supposed to flush cleanrly,
- // run all of the remaining frames first.
- if (!m_FlushType)
- {
- while (m_ThreadQueue.size())
- {
- RunFrame();
- }
- }
- break;
- }
- }
- }
- /**
- * Run the frame.
- */
- RunFrame();
-
- /**
- * wait in between threads if specified
- */
- if (m_think_time)
- {
- m_Threader->ThreadSleep(m_think_time);
- }
- }
-
- if (m_pHooks)
- {
- m_pHooks->OnWorkerStop(this);
- }
-}
-
-SWThreadHandle *ThreadWorker::PopThreadFromQueue()
-{
- if (m_state <= Worker_Stopped && !m_QueueLock)
- {
- return NULL;
- }
-
- SWThreadHandle *swt;
- m_QueueLock->Lock();
- swt = BaseWorker::PopThreadFromQueue();
- m_QueueLock->Unlock();
-
- return swt;
-}
-
-void ThreadWorker::AddThreadToQueue(SWThreadHandle *pHandle)
-{
- if (m_state <= Worker_Stopped)
- {
- return;
- }
-
- m_QueueLock->Lock();
- BaseWorker::AddThreadToQueue(pHandle);
- if (m_Waiting)
- {
- m_AddSignal->Signal();
- }
- m_QueueLock->Unlock();
-}
-
-WorkerState ThreadWorker::GetStatus(unsigned int *threads)
-{
- WorkerState state;
-
- m_StateLock->Lock();
- state = BaseWorker::GetStatus(threads);
- m_StateLock->Unlock();
-
- return state;
-}
-
-bool ThreadWorker::Start()
-{
- if (m_state == Worker_Invalid)
- {
- if (m_Threader == NULL)
- {
- return false;
- }
- } else if (m_state != Worker_Stopped) {
- return false;
- }
-
- m_Waiting = false;
- m_QueueLock = m_Threader->MakeMutex();
- m_StateLock = m_Threader->MakeMutex();
- m_PauseSignal = m_Threader->MakeEventSignal();
- m_AddSignal = m_Threader->MakeEventSignal();
- m_state = Worker_Running;
- ThreadParams pt;
- pt.flags = Thread_Default;
- pt.prio = ThreadPrio_Normal;
- me = m_Threader->MakeThread(this, &pt);
-
- return true;
-}
-
-bool ThreadWorker::Stop(bool flush_cancel)
-{
- if (m_state == Worker_Invalid || m_state == Worker_Stopped)
- {
- return false;
- }
-
- WorkerState oldstate;
-
- //set new state
- m_StateLock->Lock();
- oldstate = m_state;
- m_state = Worker_Stopped;
- m_FlushType = flush_cancel;
- m_StateLock->Unlock();
-
- if (oldstate == Worker_Paused)
- {
- Unpause();
- } else {
- m_QueueLock->Lock();
- if (m_Waiting)
- {
- m_AddSignal->Signal();
- }
- m_QueueLock->Unlock();
- }
-
- me->WaitForThread();
- //destroy it
- me->DestroyThis();
- //flush all remaining events
- Flush(true);
-
- //free mutex locks
- m_QueueLock->DestroyThis();
- m_StateLock->DestroyThis();
- m_PauseSignal->DestroyThis();
- m_AddSignal->DestroyThis();
-
- //invalidizzle
- m_QueueLock = NULL;
- m_StateLock = NULL;
- m_PauseSignal = NULL;
- m_AddSignal = NULL;
- me = NULL;
-
- return true;
-}
-
-bool ThreadWorker::Pause()
-{
- if (m_state != Worker_Running)
- {
- return false;
- }
-
- m_StateLock->Lock();
- m_state = Worker_Paused;
- m_StateLock->Unlock();
-
- return true;
-}
-
-
-bool ThreadWorker::Unpause()
-{
- if (m_state != Worker_Paused)
- {
- return false;
- }
-
- m_StateLock->Lock();
- m_state = Worker_Running;
- m_StateLock->Unlock();
- m_PauseSignal->Signal();
- if (m_Waiting)
- {
- m_AddSignal->Signal();
- }
-
- return true;
-}