369 lines
8.9 KiB
C++
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
|
|
|