added threader to core (not used yet)
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401090
This commit is contained in:
parent
8bca9a9b32
commit
b13e48ae0b
35
core/ThreadSupport.cpp
Normal file
35
core/ThreadSupport.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ThreadSupport.h"
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
|
||||||
|
#if defined PLATFORM_POSIX
|
||||||
|
#include "thread/PosixThreads.h"
|
||||||
|
#elif defined PLATFORM_WINDOWS
|
||||||
|
#include "thread/WinThreads.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MainThreader g_MainThreader;
|
||||||
|
IThreader *g_pThreader = &g_MainThreader;
|
||||||
|
|
||||||
|
class RegThreadStuff : public SMGlobalClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
g_ShareSys.AddInterface(NULL, g_pThreader);
|
||||||
|
}
|
||||||
|
};
|
33
core/ThreadSupport.h
Normal file
33
core/ThreadSupport.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod Threader API
|
||||||
|
* 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
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
||||||
|
#define _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
||||||
|
|
||||||
|
#include <IThreader.h>
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
extern IThreader *g_pThreader;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
@ -41,7 +41,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\;..\systems;..\..\public;..\..\public\sourcepawn"
|
AdditionalIncludeDirectories="..\;..\systems;..\..\public;..\..\public\sourcepawn"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@ -120,7 +120,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\;..\systems;..\..\public;..\..\public\sourcepawn"
|
AdditionalIncludeDirectories="..\;..\systems;..\..\public;..\..\public\sourcepawn"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD;SM_DEFAULT_THREADER"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
RuntimeTypeInfo="false"
|
RuntimeTypeInfo="false"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@ -289,6 +289,10 @@
|
|||||||
RelativePath="..\TextParsers.cpp"
|
RelativePath="..\TextParsers.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ThreadSupport.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\TimerSys.cpp"
|
RelativePath="..\TimerSys.cpp"
|
||||||
>
|
>
|
||||||
@ -391,6 +395,10 @@
|
|||||||
RelativePath="..\sm_autonatives.h"
|
RelativePath="..\sm_autonatives.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sm_cachelist.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\sm_fastlink.h"
|
RelativePath="..\sm_fastlink.h"
|
||||||
>
|
>
|
||||||
@ -407,6 +415,14 @@
|
|||||||
RelativePath="..\..\public\sm_platform.h"
|
RelativePath="..\..\public\sm_platform.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sm_queue.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sm_simple_prioqueue.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\sm_srvcmds.h"
|
RelativePath="..\sm_srvcmds.h"
|
||||||
>
|
>
|
||||||
@ -439,6 +455,10 @@
|
|||||||
RelativePath="..\TextParsers.h"
|
RelativePath="..\TextParsers.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\ThreadSupport.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\TimerSys.h"
|
RelativePath="..\TimerSys.h"
|
||||||
>
|
>
|
||||||
@ -913,6 +933,42 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Threader"
|
||||||
|
>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\BaseWorker.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\ThreadWorker.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\WinThreads.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\BaseWorker.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\ThreadWorker.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\thread\WinThreads.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
263
core/thread/BaseWorker.cpp
Normal file
263
core/thread/BaseWorker.cpp
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BaseWorker.h"
|
||||||
|
|
||||||
|
BaseWorker::BaseWorker() :
|
||||||
|
m_perFrame(SM_DEFAULT_THREADS_PER_FRAME),
|
||||||
|
m_state(Worker_Stopped)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseWorker::~BaseWorker()
|
||||||
|
{
|
||||||
|
if (m_state != Worker_Stopped || m_state != Worker_Invalid)
|
||||||
|
Stop(true);
|
||||||
|
|
||||||
|
if (m_ThreadQueue.size())
|
||||||
|
Flush(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorker::MakeThread(IThread *pThread)
|
||||||
|
{
|
||||||
|
ThreadParams pt;
|
||||||
|
|
||||||
|
pt.flags = Thread_AutoRelease;
|
||||||
|
pt.prio = ThreadPrio_Normal;
|
||||||
|
|
||||||
|
MakeThread(pThread, &pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
IThreadHandle *BaseWorker::MakeThread(IThread *pThread, ThreadFlags flags)
|
||||||
|
{
|
||||||
|
ThreadParams pt;
|
||||||
|
|
||||||
|
pt.flags = flags;
|
||||||
|
pt.prio = ThreadPrio_Normal;
|
||||||
|
|
||||||
|
return MakeThread(pThread, &pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
IThreadHandle *BaseWorker::MakeThread(IThread *pThread, const ThreadParams *params)
|
||||||
|
{
|
||||||
|
if (m_state != Worker_Running)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
SWThreadHandle *swt = new SWThreadHandle(this, params, pThread);
|
||||||
|
|
||||||
|
AddThreadToQueue(swt);
|
||||||
|
|
||||||
|
return swt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorker::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
|
||||||
|
{
|
||||||
|
max = ThreadPrio_Normal;
|
||||||
|
min = ThreadPrio_Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int BaseWorker::Flush(bool flush_cancel)
|
||||||
|
{
|
||||||
|
SWThreadHandle *swt;
|
||||||
|
unsigned int num = 0;
|
||||||
|
|
||||||
|
while ((swt=PopThreadFromQueue()) != NULL)
|
||||||
|
{
|
||||||
|
swt->m_state = Thread_Done;
|
||||||
|
if (!flush_cancel)
|
||||||
|
swt->pThread->RunThread(swt);
|
||||||
|
swt->pThread->OnTerminate(swt, flush_cancel);
|
||||||
|
if (swt->m_params.flags & Thread_AutoRelease)
|
||||||
|
delete swt;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWThreadHandle *BaseWorker::PopThreadFromQueue()
|
||||||
|
{
|
||||||
|
if (!m_ThreadQueue.size())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
SourceHook::List<SWThreadHandle *>::iterator begin;
|
||||||
|
SWThreadHandle *swt;
|
||||||
|
|
||||||
|
begin = m_ThreadQueue.begin();
|
||||||
|
swt = (*begin);
|
||||||
|
m_ThreadQueue.erase(begin);
|
||||||
|
|
||||||
|
return swt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
|
||||||
|
{
|
||||||
|
m_ThreadQueue.push_back(pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int BaseWorker::GetMaxThreadsPerFrame()
|
||||||
|
{
|
||||||
|
return m_perFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerState BaseWorker::GetStatus(unsigned int *threads)
|
||||||
|
{
|
||||||
|
if (threads)
|
||||||
|
*threads = m_perFrame;
|
||||||
|
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int BaseWorker::RunFrame()
|
||||||
|
{
|
||||||
|
unsigned int done = 0;
|
||||||
|
unsigned int max = GetMaxThreadsPerFrame();
|
||||||
|
SWThreadHandle *swt = NULL;
|
||||||
|
IThread *pThread = NULL;
|
||||||
|
|
||||||
|
while (done < max)
|
||||||
|
{
|
||||||
|
if ((swt=PopThreadFromQueue()) == NULL)
|
||||||
|
break;
|
||||||
|
pThread = swt->pThread;
|
||||||
|
swt->m_state = Thread_Running;
|
||||||
|
pThread->RunThread(swt);
|
||||||
|
swt->m_state = Thread_Done;
|
||||||
|
pThread->OnTerminate(swt, false);
|
||||||
|
if (swt->m_params.flags & Thread_AutoRelease)
|
||||||
|
delete swt;
|
||||||
|
done++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorker::SetMaxThreadsPerFrame(unsigned int threads)
|
||||||
|
{
|
||||||
|
m_perFrame = threads;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseWorker::Start()
|
||||||
|
{
|
||||||
|
if (m_state != Worker_Invalid && m_state != Worker_Stopped)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_state = Worker_Running;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseWorker::Stop(bool flush_cancel)
|
||||||
|
{
|
||||||
|
if (m_state == Worker_Invalid || m_state == Worker_Stopped)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_state == Worker_Paused)
|
||||||
|
{
|
||||||
|
if (!Unpause())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_state = Worker_Stopped;
|
||||||
|
Flush(flush_cancel);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseWorker::Pause()
|
||||||
|
{
|
||||||
|
if (m_state != Worker_Running)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_state = Worker_Paused;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseWorker::Unpause()
|
||||||
|
{
|
||||||
|
if (m_state != Worker_Paused)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_state = Worker_Running;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
* THREAD HANDLE STUFF *
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
void SWThreadHandle::DestroyThis()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SWThreadHandle::GetParams(ThreadParams *p)
|
||||||
|
{
|
||||||
|
*p = m_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadPriority SWThreadHandle::GetPriority()
|
||||||
|
{
|
||||||
|
return m_params.prio;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadState SWThreadHandle::GetState()
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
IThreadCreator *SWThreadHandle::Parent()
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SWThreadHandle::SetPriority(ThreadPriority prio)
|
||||||
|
{
|
||||||
|
if (m_params.prio != ThreadPrio_Normal)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_params.prio = prio;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SWThreadHandle::Unpause()
|
||||||
|
{
|
||||||
|
if (m_state != Thread_Paused)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_state = Thread_Running;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SWThreadHandle::WaitForThread()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWThreadHandle::SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread) :
|
||||||
|
m_state(Thread_Paused), m_params(*p), m_parent(parent), pThread(thread)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IThread *SWThreadHandle::GetThread()
|
||||||
|
{
|
||||||
|
return pThread;
|
||||||
|
}
|
86
core/thread/BaseWorker.h
Normal file
86
core/thread/BaseWorker.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_BASEWORKER_H
|
||||||
|
#define _INCLUDE_SOURCEMOD_BASEWORKER_H
|
||||||
|
|
||||||
|
#include "sh_list.h"
|
||||||
|
#include "ThreadSupport.h"
|
||||||
|
|
||||||
|
#define SM_DEFAULT_THREADS_PER_FRAME 1
|
||||||
|
|
||||||
|
class BaseWorker;
|
||||||
|
|
||||||
|
//SW = Simple Wrapper
|
||||||
|
class SWThreadHandle : public IThreadHandle
|
||||||
|
{
|
||||||
|
friend class BaseWorker;
|
||||||
|
public:
|
||||||
|
SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread);
|
||||||
|
IThread *GetThread();
|
||||||
|
public:
|
||||||
|
//NOTE: We don't support this by default.
|
||||||
|
//It's specific usage that'd require many mutexes
|
||||||
|
virtual bool WaitForThread();
|
||||||
|
public:
|
||||||
|
virtual void DestroyThis();
|
||||||
|
virtual IThreadCreator *Parent();
|
||||||
|
virtual void GetParams(ThreadParams *ptparams);
|
||||||
|
public:
|
||||||
|
//Priorities not supported by default.
|
||||||
|
virtual ThreadPriority GetPriority();
|
||||||
|
virtual bool SetPriority(ThreadPriority prio);
|
||||||
|
public:
|
||||||
|
virtual ThreadState GetState();
|
||||||
|
virtual bool Unpause();
|
||||||
|
private:
|
||||||
|
ThreadState m_state;
|
||||||
|
ThreadParams m_params;
|
||||||
|
IThreadCreator *m_parent;
|
||||||
|
IThread *pThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseWorker : public IThreadWorker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseWorker();
|
||||||
|
virtual ~BaseWorker();
|
||||||
|
public: //IWorker
|
||||||
|
virtual unsigned int RunFrame();
|
||||||
|
//Controls the worker
|
||||||
|
virtual bool Pause();
|
||||||
|
virtual bool Unpause();
|
||||||
|
virtual bool Start();
|
||||||
|
virtual bool Stop(bool flush_cancel);
|
||||||
|
//Flushes out any remaining threads
|
||||||
|
virtual unsigned int Flush(bool flush_cancel);
|
||||||
|
//returns status and number of threads in queue
|
||||||
|
virtual WorkerState GetStatus(unsigned int *numThreads);
|
||||||
|
public: //IThreadCreator
|
||||||
|
virtual void MakeThread(IThread *pThread);
|
||||||
|
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
|
||||||
|
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
|
||||||
|
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
|
||||||
|
public: //BaseWorker
|
||||||
|
virtual void AddThreadToQueue(SWThreadHandle *pHandle);
|
||||||
|
virtual SWThreadHandle *PopThreadFromQueue();
|
||||||
|
virtual void SetMaxThreadsPerFrame(unsigned int threads);
|
||||||
|
virtual unsigned int GetMaxThreadsPerFrame();
|
||||||
|
protected:
|
||||||
|
SourceHook::List<SWThreadHandle *> m_ThreadQueue;
|
||||||
|
unsigned int m_perFrame;
|
||||||
|
volatile WorkerState m_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_BASEWORKER_H
|
301
core/thread/PosixThreads.cpp
Normal file
301
core/thread/PosixThreads.cpp
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod Threader API
|
||||||
|
* 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
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "PosixThreads.h"
|
||||||
|
#include "ThreadWorker.h"
|
||||||
|
|
||||||
|
IThreadWorker *PosixThreader::MakeWorker(bool threaded)
|
||||||
|
{
|
||||||
|
if (threaded)
|
||||||
|
{
|
||||||
|
return new ThreadWorker(this, DEFAULT_THINK_TIME_MS);
|
||||||
|
} else {
|
||||||
|
return new BaseWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::DestroyWorker(IThreadWorker *pWorker)
|
||||||
|
{
|
||||||
|
delete pWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::ThreadSleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
usleep( ms * 1000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
|
||||||
|
{
|
||||||
|
max = ThreadPrio_Normal;
|
||||||
|
min = ThreadPrio_Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMutex *PosixThreader::MakeMutex()
|
||||||
|
{
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&mutex, NULL) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PosixMutex *pMutex = new PosixMutex(mutex);
|
||||||
|
|
||||||
|
return pMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PosixThreader::MakeThread(IThread *pThread)
|
||||||
|
{
|
||||||
|
ThreadParams defparams;
|
||||||
|
|
||||||
|
defparams.flags = Thread_AutoRelease;
|
||||||
|
defparams.prio = ThreadPrio_Normal;
|
||||||
|
|
||||||
|
MakeThread(pThread, &defparams);
|
||||||
|
}
|
||||||
|
|
||||||
|
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, ThreadFlags flags)
|
||||||
|
{
|
||||||
|
ThreadParams defparams;
|
||||||
|
|
||||||
|
defparams.flags = flags;
|
||||||
|
defparams.prio = ThreadPrio_Normal;
|
||||||
|
|
||||||
|
return MakeThread(pThread, &defparams);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Posix_ThreadGate(void *param)
|
||||||
|
{
|
||||||
|
PosixThreader::ThreadHandle *pHandle =
|
||||||
|
reinterpret_cast<PosixThreader::ThreadHandle *>(param);
|
||||||
|
|
||||||
|
//Block this thread from being started initially.
|
||||||
|
pthread_mutex_lock(&pHandle->m_runlock);
|
||||||
|
//if we get here, we've obtained the lock and are allowed to run.
|
||||||
|
//unlock and continue.
|
||||||
|
pthread_mutex_unlock(&pHandle->m_runlock);
|
||||||
|
|
||||||
|
pHandle->m_run->RunThread(pHandle);
|
||||||
|
|
||||||
|
ThreadParams params;
|
||||||
|
pthread_mutex_lock(&pHandle->m_statelock);
|
||||||
|
pHandle->m_state = Thread_Done;
|
||||||
|
pHandle->GetParams(¶ms);
|
||||||
|
pthread_mutex_unlock(&pHandle->m_statelock);
|
||||||
|
|
||||||
|
pHandle->m_run->OnTerminate(pHandle, false);
|
||||||
|
if (params.flags & Thread_AutoRelease)
|
||||||
|
delete pHandle;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadParams g_defparams;
|
||||||
|
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, const ThreadParams *params)
|
||||||
|
{
|
||||||
|
if (params == NULL)
|
||||||
|
params = &g_defparams;
|
||||||
|
|
||||||
|
PosixThreader::ThreadHandle *pHandle =
|
||||||
|
new PosixThreader::ThreadHandle(this, pThread, params);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pHandle->m_runlock);
|
||||||
|
|
||||||
|
int err;
|
||||||
|
err = pthread_create(&pHandle->m_thread, NULL, Posix_ThreadGate, (void *)pHandle);
|
||||||
|
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&pHandle->m_runlock);
|
||||||
|
delete pHandle;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't bother setting priority...
|
||||||
|
|
||||||
|
if (!(pHandle->m_params.flags & Thread_CreateSuspended))
|
||||||
|
{
|
||||||
|
pHandle->m_state = Thread_Running;
|
||||||
|
err = pthread_mutex_unlock(&pHandle->m_runlock);
|
||||||
|
if (err != 0)
|
||||||
|
pHandle->m_state = Thread_Paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEventSignal *PosixThreader::MakeEventSignal()
|
||||||
|
{
|
||||||
|
return new PosixEventSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
**** Mutexes ****
|
||||||
|
*****************/
|
||||||
|
|
||||||
|
PosixThreader::PosixMutex::~PosixMutex()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PosixThreader::PosixMutex::TryLock()
|
||||||
|
{
|
||||||
|
int err = pthread_mutex_trylock(&m_mutex);
|
||||||
|
|
||||||
|
return (err == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixMutex::Lock()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixMutex::Unlock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixMutex::DestroyThis()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* Thread Handles *
|
||||||
|
******************/
|
||||||
|
|
||||||
|
PosixThreader::ThreadHandle::ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params) :
|
||||||
|
m_parent(parent), m_params(*params), m_run(run), m_state(Thread_Paused)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&m_runlock, NULL);
|
||||||
|
pthread_mutex_init(&m_statelock, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PosixThreader::ThreadHandle::~ThreadHandle()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&m_runlock);
|
||||||
|
pthread_mutex_destroy(&m_statelock);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PosixThreader::ThreadHandle::WaitForThread()
|
||||||
|
{
|
||||||
|
void *arg;
|
||||||
|
|
||||||
|
if (pthread_join(m_thread, &arg) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadState PosixThreader::ThreadHandle::GetState()
|
||||||
|
{
|
||||||
|
ThreadState state;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&m_statelock);
|
||||||
|
state = m_state;
|
||||||
|
pthread_mutex_unlock(&m_statelock);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
IThreadCreator *PosixThreader::ThreadHandle::Parent()
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::ThreadHandle::DestroyThis()
|
||||||
|
{
|
||||||
|
if (m_params.flags & Thread_AutoRelease)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
|
||||||
|
{
|
||||||
|
if (!ptparams)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*ptparams = m_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadPriority PosixThreader::ThreadHandle::GetPriority()
|
||||||
|
{
|
||||||
|
return ThreadPrio_Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PosixThreader::ThreadHandle::SetPriority(ThreadPriority prio)
|
||||||
|
{
|
||||||
|
return (prio == ThreadPrio_Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PosixThreader::ThreadHandle::Unpause()
|
||||||
|
{
|
||||||
|
if (m_state != Thread_Paused)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_state = Thread_Running;
|
||||||
|
|
||||||
|
if (pthread_mutex_unlock(&m_runlock) != 0)
|
||||||
|
{
|
||||||
|
m_state = Thread_Paused;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
* EVENT SIGNALS *
|
||||||
|
*****************/
|
||||||
|
|
||||||
|
PosixThreader::PosixEventSignal::PosixEventSignal()
|
||||||
|
{
|
||||||
|
pthread_cond_init(&m_cond, NULL);
|
||||||
|
pthread_mutex_init(&m_mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PosixThreader::PosixEventSignal::~PosixEventSignal()
|
||||||
|
{
|
||||||
|
pthread_cond_destroy(&m_cond);
|
||||||
|
pthread_mutex_destroy(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixEventSignal::Wait()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
pthread_cond_wait(&m_cond, &m_mutex);
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixEventSignal::Signal()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
pthread_cond_broadcast(&m_cond);
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PosixThreader::PosixEventSignal::DestroyThis()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
107
core/thread/PosixThreads.h
Normal file
107
core/thread/PosixThreads.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod Threader API
|
||||||
|
* 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
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_POSIXTHREADS_H_
|
||||||
|
#define _INCLUDE_POSIXTHREADS_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "IThreader.h"
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
void *Posix_ThreadGate(void *param);
|
||||||
|
|
||||||
|
class PosixThreader : public IThreader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class ThreadHandle : public IThreadHandle
|
||||||
|
{
|
||||||
|
friend class PosixThreader;
|
||||||
|
friend void *Posix_ThreadGate(void *param);
|
||||||
|
public:
|
||||||
|
ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params);
|
||||||
|
virtual ~ThreadHandle();
|
||||||
|
public:
|
||||||
|
virtual bool WaitForThread();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
virtual IThreadCreator *Parent();
|
||||||
|
virtual void GetParams(ThreadParams *ptparams);
|
||||||
|
virtual ThreadPriority GetPriority();
|
||||||
|
virtual bool SetPriority(ThreadPriority prio);
|
||||||
|
virtual ThreadState GetState();
|
||||||
|
virtual bool Unpause();
|
||||||
|
protected:
|
||||||
|
IThreader *m_parent; //Parent handle
|
||||||
|
pthread_t m_thread; //Windows HANDLE
|
||||||
|
ThreadParams m_params; //Current Parameters
|
||||||
|
IThread *m_run; //Runnable context
|
||||||
|
pthread_mutex_t m_statelock;
|
||||||
|
pthread_mutex_t m_runlock;
|
||||||
|
ThreadState m_state; //internal state
|
||||||
|
};
|
||||||
|
class PosixMutex : public IMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PosixMutex(pthread_mutex_t m) : m_mutex(m)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
virtual ~PosixMutex();
|
||||||
|
public:
|
||||||
|
virtual bool TryLock();
|
||||||
|
virtual void Lock();
|
||||||
|
virtual void Unlock();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
protected:
|
||||||
|
pthread_mutex_t m_mutex;
|
||||||
|
};
|
||||||
|
class PosixEventSignal : public IEventSignal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PosixEventSignal();
|
||||||
|
virtual ~PosixEventSignal();
|
||||||
|
public:
|
||||||
|
virtual void Wait();
|
||||||
|
virtual void Signal();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
protected:
|
||||||
|
pthread_cond_t m_cond;
|
||||||
|
pthread_mutex_t m_mutex;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
IMutex *MakeMutex();
|
||||||
|
void MakeThread(IThread *pThread);
|
||||||
|
IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
|
||||||
|
IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
|
||||||
|
void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
|
||||||
|
void ThreadSleep(unsigned int ms);
|
||||||
|
IEventSignal *MakeEventSignal();
|
||||||
|
IThreadWorker *MakeWorker(bool threaded);
|
||||||
|
void DestroyWorker(IThreadWorker *pWorker);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined SM_DEFAULT_THREADER && !defined SM_MAIN_THREADER
|
||||||
|
#define SM_MAIN_THREADER PosixThreader;
|
||||||
|
typedef class PosixThreader MainThreader;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //_INCLUDE_POSIXTHREADS_H_
|
272
core/thread/ThreadWorker.cpp
Normal file
272
core/thread/ThreadWorker.cpp
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ThreadWorker.h"
|
||||||
|
|
||||||
|
ThreadWorker::ThreadWorker() :
|
||||||
|
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(IThreader *pThreader, unsigned int thinktime) :
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
54
core/thread/ThreadWorker.h
Normal file
54
core/thread/ThreadWorker.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_THREADWORKER_H
|
||||||
|
#define _INCLUDE_SOURCEMOD_THREADWORKER_H
|
||||||
|
|
||||||
|
#include "BaseWorker.h"
|
||||||
|
|
||||||
|
#define DEFAULT_THINK_TIME_MS 500
|
||||||
|
|
||||||
|
class ThreadWorker : public BaseWorker, public IThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadWorker();
|
||||||
|
ThreadWorker(IThreader *pThreader, unsigned int thinktime=DEFAULT_THINK_TIME_MS);
|
||||||
|
virtual ~ThreadWorker();
|
||||||
|
public: //IThread
|
||||||
|
virtual void OnTerminate(IThreadHandle *pHandle, bool cancel);
|
||||||
|
virtual void RunThread(IThreadHandle *pHandle);
|
||||||
|
public: //IWorker
|
||||||
|
//Controls the worker
|
||||||
|
virtual bool Pause();
|
||||||
|
virtual bool Unpause();
|
||||||
|
virtual bool Start();
|
||||||
|
virtual bool Stop(bool flush_cancel);
|
||||||
|
//returns status and number of threads in queue
|
||||||
|
virtual WorkerState GetStatus(unsigned int *numThreads);
|
||||||
|
public: //BaseWorker
|
||||||
|
virtual void AddThreadToQueue(SWThreadHandle *pHandle);
|
||||||
|
virtual SWThreadHandle *PopThreadFromQueue();
|
||||||
|
protected:
|
||||||
|
IThreader *m_Threader;
|
||||||
|
IMutex *m_QueueLock;
|
||||||
|
IMutex *m_StateLock;
|
||||||
|
IEventSignal *m_PauseSignal;
|
||||||
|
IEventSignal *m_AddSignal;
|
||||||
|
IThreadHandle *me;
|
||||||
|
unsigned int m_think_time;
|
||||||
|
volatile bool m_Waiting;
|
||||||
|
volatile bool m_FlushType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_THREADWORKER_H
|
318
core/thread/WinThreads.cpp
Normal file
318
core/thread/WinThreads.cpp
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WinThreads.h"
|
||||||
|
#include "ThreadWorker.h"
|
||||||
|
|
||||||
|
IThreadWorker *WinThreader::MakeWorker(bool threaded)
|
||||||
|
{
|
||||||
|
if (threaded)
|
||||||
|
{
|
||||||
|
return new ThreadWorker(this, DEFAULT_THINK_TIME_MS);
|
||||||
|
} else {
|
||||||
|
return new BaseWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinThreader::DestroyWorker(IThreadWorker *pWorker)
|
||||||
|
{
|
||||||
|
delete pWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinThreader::ThreadSleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
Sleep((DWORD)ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMutex *WinThreader::MakeMutex()
|
||||||
|
{
|
||||||
|
HANDLE mutex = CreateMutexA(NULL, FALSE, NULL);
|
||||||
|
|
||||||
|
if (mutex == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
WinMutex *pMutex = new WinMutex(mutex);
|
||||||
|
|
||||||
|
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<WinThreader::ThreadHandle *>(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()
|
||||||
|
{
|
||||||
|
if (m_mutex)
|
||||||
|
{
|
||||||
|
CloseHandle(m_mutex);
|
||||||
|
m_mutex = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WinThreader::WinMutex::TryLock()
|
||||||
|
{
|
||||||
|
if (!m_mutex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (WaitForSingleObject(m_mutex, 0) != WAIT_FAILED)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinThreader::WinMutex::Lock()
|
||||||
|
{
|
||||||
|
if (!m_mutex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WaitForSingleObject(m_mutex, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinThreader::WinMutex::Unlock()
|
||||||
|
{
|
||||||
|
if (!m_mutex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ReleaseMutex(m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
98
core/thread/WinThreads.h
Normal file
98
core/thread/WinThreads.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_WINTHREADS_H_
|
||||||
|
#define _INCLUDE_WINTHREADS_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "IThreader.h"
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
DWORD WINAPI Win32_ThreadGate(LPVOID param);
|
||||||
|
|
||||||
|
class WinThreader : public IThreader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class ThreadHandle : public IThreadHandle
|
||||||
|
{
|
||||||
|
friend class WinThreader;
|
||||||
|
friend DWORD WINAPI Win32_ThreadGate(LPVOID param);
|
||||||
|
public:
|
||||||
|
ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params);
|
||||||
|
virtual ~ThreadHandle();
|
||||||
|
public:
|
||||||
|
virtual bool WaitForThread();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
virtual IThreadCreator *Parent();
|
||||||
|
virtual void GetParams(ThreadParams *ptparams);
|
||||||
|
virtual ThreadPriority GetPriority();
|
||||||
|
virtual bool SetPriority(ThreadPriority prio);
|
||||||
|
virtual ThreadState GetState();
|
||||||
|
virtual bool Unpause();
|
||||||
|
protected:
|
||||||
|
IThreader *m_parent; //Parent handle
|
||||||
|
HANDLE m_thread; //Windows HANDLE
|
||||||
|
ThreadParams m_params; //Current Parameters
|
||||||
|
IThread *m_run; //Runnable context
|
||||||
|
ThreadState m_state; //internal state
|
||||||
|
CRITICAL_SECTION m_crit;
|
||||||
|
};
|
||||||
|
class WinMutex : public IMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WinMutex(HANDLE mutex) : m_mutex(mutex)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
virtual ~WinMutex();
|
||||||
|
public:
|
||||||
|
virtual bool TryLock();
|
||||||
|
virtual void Lock();
|
||||||
|
virtual void Unlock();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
protected:
|
||||||
|
HANDLE m_mutex;
|
||||||
|
};
|
||||||
|
class WinEvent : public IEventSignal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WinEvent(HANDLE event) : m_event(event)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
virtual ~WinEvent();
|
||||||
|
public:
|
||||||
|
virtual void Wait();
|
||||||
|
virtual void Signal();
|
||||||
|
virtual void DestroyThis();
|
||||||
|
public:
|
||||||
|
HANDLE m_event;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
IMutex *MakeMutex();
|
||||||
|
void MakeThread(IThread *pThread);
|
||||||
|
IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
|
||||||
|
IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
|
||||||
|
void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
|
||||||
|
void ThreadSleep(unsigned int ms);
|
||||||
|
IEventSignal *MakeEventSignal();
|
||||||
|
IThreadWorker *MakeWorker(bool threaded);
|
||||||
|
void DestroyWorker(IThreadWorker *pWorker);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined SM_DEFAULT_THREADER && !defined SM_MAIN_THREADER
|
||||||
|
#define SM_MAIN_THREADER WinThreader;
|
||||||
|
typedef class WinThreader MainThreader;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //_INCLUDE_WINTHREADS_H_
|
Loading…
Reference in New Issue
Block a user