// 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 #ifndef _INCLUDE_SOURCEMOD_THREADER_H #define _INCLUDE_SOURCEMOD_THREADER_H namespace SourceMod { enum ThreadFlags { Thread_Default = 0, //auto release handle on finish //you are not guaranteed the handle for this is valid after // calling MakeThread(), so never use it until OnTerminate is called. Thread_AutoRelease = 1, //Thread is created "suspended", meaning // it is inactive until unpaused. Thread_CreateSuspended = 2, }; enum ThreadPriority { ThreadPrio_Minimum = -8, ThreadPrio_Low = -3, ThreadPrio_Normal = 0, ThreadPrio_High = 3, ThreadPrio_Maximum = 8, }; enum ThreadState { Thread_Running = 0, Thread_Paused = 1, Thread_Done = 2, }; struct ThreadParams { ThreadParams() : flags(Thread_Default), prio(ThreadPrio_Normal) { }; ThreadFlags flags; ThreadPriority prio; }; class IThreadCreator; /** * Describes a handle to a thread */ class IThreadHandle { public: virtual ~IThreadHandle() { }; public: /** * Pauses parent thread until this thread completes. */ virtual bool WaitForThread() =0; /** * Destroys the thread handle. * This will not necessarily cancel the thread. */ virtual void DestroyThis() =0; /** * Returns the parent threader. */ virtual IThreadCreator *Parent() =0; /** * Returns the thread states. */ virtual void GetParams(ThreadParams *ptparams) =0; /** * Returns priority */ virtual ThreadPriority GetPriority() =0; /** * Sets thread priority */ virtual bool SetPriority(ThreadPriority prio) =0; /** * Gets thread state */ virtual ThreadState GetState() =0; /** * Attempts to unpause a paused thread. */ virtual bool Unpause() =0; }; /** * Describes a single unit of execution/context flow */ class IThread { public: virtual ~IThread() { }; public: //Called when the thread runs virtual void RunThread(IThreadHandle *pHandle) =0; //Called when the thread terminates. //"Cancel" is true if the thread did not finish //(this could mean suspended or terminated abruptly) virtual void OnTerminate(IThreadHandle *pHandle, bool cancel) =0; }; /** * Describes a thread creator */ class IThreadCreator { public: virtual ~IThreadCreator() { }; public: //Makes a thread and cleans up the handle for you virtual void MakeThread(IThread *pThread) =0; //Makes a thread with flag specified virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0; //Makes a thread, full options can be specified virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0; //Return priority bounds virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0; }; /** * Basic Mutex */ class IMutex { public: virtual ~IMutex() { }; public: /** * Attempts to lock, but returns instantly. */ virtual bool TryLock() =0; /** * Attempts to lock by waiting for release. */ virtual void Lock() =0; /** * Unlocks mutex. */ virtual void Unlock() =0; /** * Frees the mutex handle. */ virtual void DestroyThis() =0; }; class IEventSignal { public: virtual ~IEventSignal() { }; public: /** * Waits for the signal. */ virtual void Wait() =0; /** * Triggers the signal. * Resets the signals after triggering. */ virtual void Signal() =0; /** * Frees the signal handle. */ virtual void DestroyThis() =0; }; /** * Describes a threading system */ class IThreader : public IThreadCreator { public: virtual IMutex *MakeMutex() =0; virtual void MakeThread(IThread *pThread) =0; virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0; virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0; virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0; virtual void ThreadSleep(unsigned int ms) =0; /** * Creates a non-signalled event. */ virtual IEventSignal *MakeEventSignal() =0; }; enum WorkerState { Worker_Invalid = -3, Worker_Stopped = -2, Worker_Paused = -1, Worker_Running, }; /** * This is an extension of the threader that is implemented. * It "simulates" threading in a queue, and processes the queue whenever * RunFrame is called (leaving it up to the implementation). * Worker may or may not be started upon instantiation. */ class IWorker : public IThreadCreator { public: virtual unsigned int RunFrame() =0; virtual void MakeThread(IThread *pThread) =0; virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0; virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0; virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0; public: //Controls the worker virtual bool Pause() =0; virtual bool Unpause() =0; virtual bool Start() =0; //If flush is true, all remaining tasks will be cancelled. //Otherwise, it will wait until the tasks have been depleted, then // end. virtual bool Stop(bool flush_cancel) =0; //Flushes out any remaining threads virtual unsigned int Flush(bool flush_cancel) =0; //returns status and number of threads in queue virtual WorkerState GetStatus(unsigned int *numThreads) =0; }; }; #endif //_INCLUDE_SOURCEMOD_THREADER_H