Files
libsst/Include/ZUtil/ZThread.hpp
2026-04-03 00:22:39 -05:00

369 lines
8.9 KiB
C++

/*
ZThread.hpp
Author : James Russell <jcrussell@762studios.com>
Created: 07/04/09
Purpose :
Wrapper class to allow easy thread creation. By making a class that is
a subclass of ZThread and defining the run() method, a thread 'object' can
be created that allows for greater consistency and when dealing with thread
resources.
License:
TODO
*/
#ifndef _ZTHREAD_H
#define _ZTHREAD_H
#include <ZSTL/ZList.hpp>
#include <ZSTL/ZString.hpp>
#include <ZUtil/ZConcurrency.hpp>
#include <ZUtil/ZSmartPointer.hpp>
class ZThread;
typedef void (*ZThreadCallbackFunc)(ZThread* executor, void* arg);
/*
Macro that creates an anonymous request object for marshalling code into a thread request.
Example:
TODO
@param zthread - the zthread object that should execute the request
@param argument - the void* argument to pass in (accessible as Arg)
@param wait - a boolean indicating if we should wait or not
@param code - the actual code that should be executed as part of the request (wrap in parenthesis)
*/
#define ZTHREAD_EXECUTE(zthread, argument, wait, code) \
{ \
class Z##__FUNCTION__##__LINE__##ThreadRequest : public ZThreadRequest \
{ \
protected: \
void *Arg; \
public: \
Z##__FUNCTION__##__LINE__##ThreadRequest() : ZThreadRequest(), Arg(argument) { } \
\
virtual void Execute(ZThread *_threadObj) \
{ \
code \
} \
}; \
\
zthread->AddThreadRequest(ZPtr<ZThreadRequest>(znew Z##__FUNCTION__##__LINE__##ThreadRequest), wait); \
}
//Forward declaration of ZThread
class ZThread;
//Possible return values from ZThread run
typedef enum ZThreadReturn
{
ZTR_TERMINATE, //Indicates the thread should terminate after returning from run
ZTR_LOOP, //Indicates the thread should loop after returning from run
ZTR_PAUSE, //Indicates the thread should pause after returning from run
ZTR_SIZE
} ZThreadReturn;
/*
A ZThread 'Request' object. Used for thread marshaling.
*/
class ZThreadRequest
{
friend class ZThread;
private:
//Completion Event
ZEvent CompletedEvent;
//Indicates this 'ThreadRequest' should persist until removed
bool Persist;
//Indicates to the ZThread that this request should stop running immediately
//This value is checked before execution
bool Stop;
public:
/*
Default Constructor.
@param _persist - boolean indicating this thread request should execute continuously until
the ZThread object is deleted
*/
ZThreadRequest(bool _persist = false)
: CompletedEvent(), Persist(_persist), Stop(false) { }
/*
Destructor.
Destroys the concurrency event.
*/
virtual ~ZThreadRequest() { }
/*
virtual public ZThreadRequest::Execute
Virtual method, which defines the thread request to be executed. The function will be executed
from within the ZThread object's thread context. If this method is not overridden and Func is not
NULL, Func is called with the provided argument.
@param _threadObj - the ZThread object executing this request
@return (void)
*/
virtual void Execute(ZThread *_threadObj) = 0;
/*
public ZThreadRequest::StopExecution
Stops execution of the thread request, provided it has not executed yet.
@return (void)
*/
void StopExecution() { this->Stop = true; }
/*
public ZThreadRequest::Wait
Blocks until after the thread request has been executed.
@return (void)
*/
void Wait() { CompletedEvent.Wait(); }
};
/*
ZThread object class. Should be subclassed to make a threadable 'object'.
*/
class ZThread
{
private:
DISABLE_COPY_AND_ASSIGN(ZThread);
public:
/*
Default Constructor.
@param _threadName - the name of this thread
*/
ZThread(ZString _threadName = "");
/*
Destructor for the ZThread Object. When the ZThread object is deleted, the destructor will wait on
the thread to terminate and return resources to the system.
*/
virtual ~ZThread();
/*
public ZThread::AddThreadRequest()
Adds a callback that will be executed when the thread loops.
@param _request - the thread request to add to the thread's context
@return (void)
*/
void AddThreadRequest(ZPtr<ZThreadRequest> _request, bool _wait = false);
/*
public ZThread::AddCallbackRequest()
Adds a callback to be executed by the thread. It can be executed synchronously or asynchronously.
@param function - The function to execute
@param arg - The argument
@param async - If true, this returns immediately, otherwise it waits for the function to execute.
@return (void)
*/
void AddCallbackRequest(ZThreadCallbackFunc function, void* arg, bool async);
/*
public ZThread::GetThreadID
Gets the thread ID of the thread object.
@return (uint32_t) - int that is the thread id of the thread object
*/
uint32_t GetThreadId();
/*
public ZThread::GetThreadName
Gets the thread name of the ZThread object. The name of a thread is either a
string value of the thread id or a name that was set by the ZThread object.
@return (ZString) - string representing the 'name' of this thread
*/
ZString GetThreadName();
/*
public ZThread::PauseThread
Tells the user thread to pause.
@return (void)
*/
void PauseThread();
/*
public ZThread::RestartThread
Restarts a paused thread.
@return (void)
*/
void RestartThread();
/*
public ZThread::ThreadRunning
Indicates if a ZThread object is executing it's run method or is paused.
@return (bool) - boolean indicating thread is running or is paused
*/
bool ThreadRunning();
/*
public ZThread::ThreadInitialized
Returns true if the ZThread object has called it's initThread() method and returned.
@return (bool) - boolean indicating the thread is initialized
*/
bool ThreadInitialized();
/*
public ZThread::ShutdownThread
Tells the user thread to shutdown. Blocks until it happens.
@return (void)
*/
void ShutdownThread();
/*
public ZThread::StartThread
When StartThread is called on a class that extends ZThread, a thread will be created
that will call the run() function implemented by the subclass.
@return (bool) - boolean indicating the thread has started successfully
*/
bool StartThread();
/*
public ZThread::WaitInitialized
Caller waits until the ZThread has initialized.
@return (void)
@context (all)
*/
void WaitInitialized();
/*
public ZThread::WaitShutdown
Caller waits until the ZThread has shutdown.
@return (void)
@context (all)
*/
void WaitShutdown();
protected:
//Thread 'name' of this thread
ZString ThreadName;
//Boolean field which, when set to true, indicates the thread should terminate.
bool bShouldShutdown;
//Boolean field which, when set to true, indicates the thread should pause.
bool bShouldPause;
/*
This is a wrapper around the user run() method, which calls that method in a loop, executing
thread requests and setting the condition variables appropriately.
*/
void Run();
/*
Executes the thread requests that may be pending at the time it is called by the subclass.
*/
void ExecuteThreadRequests();
/*
Initialization method which is called when the thread starts. Does not have to be overridden, but any
thread specific initialization that must be done in the thread context of the ZThread object needs
to be defined here.
*/
virtual void initThread() { }
/*
Shutdown method which is called when the thread terminates. Does not have to be overridden, but any
thread specific shutdown requirements that must be done in the thread context of the ZThread object
needs to be defined here.
*/
virtual void shutdownThread() { }
/*
This method must be implemented by the ZThread subclass. This is the 'main' function of execution for
the newly created thread.
@param _dt - the time (in ms) since last time run was called
@return - a ZTHREAD_RETURN value indicating whether the thread should run once (ZTR_TERMINATE),
loop (ZTR_RETURN), or pause (ZTR_PAUSE).
*/
virtual ZThreadReturn run(uint64_t _dt) = 0;
bool IsCallerTheThread();
private:
struct ZThreadCallbackRequest {
ZThreadCallbackFunc callback;
void* arg;
SST_Event doneEvent;
};
//Thread context of this thread
ZThreadContext ThreadContext;
//The mutex for use by this thread object for handling thread marshaling.
ZMutex ThreadLock;
//The event signaled when the thread has finished initializing
ZEvent InitEvent;
//Previous tick count for this thread object
uint64_t PreviousTickCount;
//Current tick count for this thread object
uint64_t CurrentTickCount;
//Boolean field which, when set to true, indicates the thread is initialized and running.
bool bIsRunning;
//Boolean field which, when set to true, indicates the thread has called and returned from initThread()
bool bIsInitialized;
//List of callbacks that will occur when the ZThread object runs.
ZList< ZPtr<ZThreadRequest> > ZTRCallbacks; // ZTR callbacks
ZList< ZThreadCallbackRequest > Callbacks; // Simple (non-object) callbacks
/*
Proxy method called by StartThread() which will call initThread and Run on the ZThread Object.
@param _runnable - a pointer to the ZThread object to run
@return - integer condition (not used)
*/
static int InitThread(void *_runnable);
};
#endif