amxmodx/modules/mysqlx/thread/BaseWorker.cpp
2015-10-02 23:22:21 +02:00

260 lines
4.4 KiB
C++

// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include "BaseWorker.h"
#include <amtl/am-linkedlist.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.length())
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.length())
return NULL;
ke::LinkedList<SWThreadHandle *>::iterator begin;
SWThreadHandle *swt;
begin = m_ThreadQueue.begin();
swt = (*begin);
m_ThreadQueue.erase(begin);
return swt;
}
void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
{
m_ThreadQueue.append(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;
}