etqw-sdk/source/idlib/threading/Thread.cpp

207 lines
3.9 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#include "../sys/threading/SysThread.h"
/*
=============
sdThread::sdThread
=============
*/
sdThread::sdThread( sdThreadProcess* process, threadPriority_e priority, unsigned int stackSize ) :
priority( priority ),
isWorker( false ),
isRunning( false ),
isStopping( false ) {
parms.process = process;
parms.thread = this;
sdSysThread::Create( (threadProc_t)ThreadProc, &parms, handle, priority, stackSize );
}
/*
=============
sdThread::~sdThread
=============
*/
sdThread::~sdThread() {
Mem_Free( parms.parm );
parms.parm = NULL;
sdSysThread::Destroy( handle );
}
/*
=============
sdThread::Destroy
=============
*/
void sdThread::Destroy() {
delete this;
}
/*
=============
sdThread::Start
=============
*/
bool sdThread::Start( const void *parm, size_t size ) {
if ( NULL == parms.process || isRunning ) {
return false;
}
if ( NULL != parm ) {
parms.parm = Mem_Alloc( size );
::memcpy( parms.parm, parm, size );
} else {
parms.parm = NULL;
}
parms.process->Start();
if ( !sdSysThread::Start( handle ) ) {
return false;
}
isRunning = true;
return true;
}
/*
=============
sdThread::StartWorker
=============
*/
bool sdThread::StartWorker( const void *parm, size_t size ) {
isWorker = true;
#ifdef _WIN32
hEventWorkerDone = CreateEvent( NULL, FALSE, FALSE, NULL );
hEventMoreWorkToDo = CreateEvent( NULL, FALSE, FALSE, NULL );
#endif
bool result = Start( parm, size );
#ifdef _WIN32
DWORD dwRet = WaitForSingleObject( hEventWorkerDone, INFINITE );
dwRet; // shut compiler up
#endif
return result;
}
/*
=============
sdThread::SignalWork
=============
*/
void sdThread::SignalWork() {
#ifdef _WIN32
SetEvent( hEventMoreWorkToDo );
#endif
}
/*
=============
sdThread::Stop
=============
*/
void sdThread::Stop() {
isStopping = true;
parms.process->Stop();
}
/*
=============
sdThread::Join
=============
*/
void sdThread::Join() {
if ( isWorker ) {
#ifdef _WIN32
DWORD dwRet = WaitForSingleObject( hEventWorkerDone, INFINITE );
dwRet; // shut compiler up
#endif
} else {
sdSysThread::Join( handle );
Mem_Free( parms.parm );
parms.parm = NULL;
}
}
/*
=============
sdThread::SetPriority
=============
*/
void sdThread::SetPriority( const threadPriority_e priority ) {
sdSysThread::SetPriority( handle, priority );
}
/*
=============
sdThread::SetProcessor
=============
*/
void sdThread::SetProcessor( const unsigned int processor ) {
sdSysThread::SetProcessor( handle, processor );
}
/*
=============
sdThread::SetName
=============
*/
void sdThread::SetName( const char* name ) {
this->name = name;
sdSysThread::SetName( handle, name );
}
#if defined( _WIN32 )
/*
=============
sdThread::ThreadProc
=============
*/
unsigned int sdThread::ThreadProc( sdThreadParms* parms ) {
// This doesn't appear to work for suspended threads - so we call it once more on thread start
sdSysThread::SetName( parms->thread->handle, parms->thread->name.c_str() );
unsigned int retVal;
if ( parms->thread->isWorker ) {
do {
#ifdef _WIN32
DWORD dwRet = SignalObjectAndWait( parms->thread->hEventWorkerDone, parms->thread->hEventMoreWorkToDo, INFINITE, FALSE );
dwRet; // shut compiler up
#endif
retVal = parms->process->Run( parms->parm );
} while( !parms->thread->isStopping );
} else {
retVal = parms->process->Run( parms->parm );
}
parms->thread->isRunning = false;
return sdSysThread::Exit( retVal );
}
#else
/*
=============
sdThread::ThreadProc
=============
*/
void* sdThread::ThreadProc( void* p ) {
sdThreadParms *parms = static_cast< sdThreadParms* >( p );
unsigned int retVal = parms->process->Run( parms->parm );
return sdSysThread::Exit( retVal );
}
#endif