00001 /** 00002 * vim: set ts=4 : 00003 * ============================================================================= 00004 * SourceMod 00005 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. 00006 * ============================================================================= 00007 * 00008 * This program is free software; you can redistribute it and/or modify it under 00009 * the terms of the GNU General Public License, version 3.0, as published by the 00010 * Free Software Foundation. 00011 * 00012 * This program is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00015 * details. 00016 * 00017 * You should have received a copy of the GNU General Public License along with 00018 * this program. If not, see <http://www.gnu.org/licenses/>. 00019 * 00020 * As a special exception, AlliedModders LLC gives you permission to link the 00021 * code of this program (as well as its derivative works) to "Half-Life 2," the 00022 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 00023 * by the Valve Corporation. You must obey the GNU General Public License in 00024 * all respects for all other code used. Additionally, AlliedModders LLC grants 00025 * this exception to all derivative works. AlliedModders LLC defines further 00026 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 00027 * or <http://www.sourcemod.net/license.php>. 00028 * 00029 * Version: $Id: IThreader.h 1964 2008-03-27 04:54:56Z damagedsoul $ 00030 */ 00031 00032 #ifndef _INCLUDE_SOURCEMOD_THREADER_H 00033 #define _INCLUDE_SOURCEMOD_THREADER_H 00034 00035 /** 00036 * @file IThreader.h 00037 * @brief Contains platform independent routines for threading. 00038 */ 00039 00040 #include <IShareSys.h> 00041 00042 #define SMINTERFACE_THREADER_NAME "IThreader" 00043 #define SMINTERFACE_THREADER_VERSION 2 00044 00045 namespace SourceMod 00046 { 00047 /** 00048 * @brief Thread creation flags 00049 */ 00050 enum ThreadFlags 00051 { 00052 Thread_Default = 0, 00053 /** 00054 * @brief Auto-release handle on finish 00055 * 00056 * You are not guaranteed the handle for this is valid after 00057 * calling MakeThread(), so never use it until OnTerminate is called. 00058 */ 00059 Thread_AutoRelease = 1, 00060 /** 00061 * @brief Thread is created "suspended", meaning it is inactive until unpaused. 00062 */ 00063 Thread_CreateSuspended = 2, 00064 }; 00065 00066 /** 00067 * @brief Specifies thread priority levels. 00068 */ 00069 enum ThreadPriority 00070 { 00071 ThreadPrio_Minimum = -8, 00072 ThreadPrio_Low = -3, 00073 ThreadPrio_Normal = 0, 00074 ThreadPrio_High = 3, 00075 ThreadPrio_Maximum = 8, 00076 }; 00077 00078 /** 00079 * @brief The current state of a thread. 00080 */ 00081 enum ThreadState 00082 { 00083 Thread_Running = 0, 00084 Thread_Paused = 1, 00085 Thread_Done = 2, 00086 }; 00087 00088 /** 00089 * @brief Thread-specific parameters. 00090 */ 00091 struct ThreadParams 00092 { 00093 /** Constructor */ 00094 ThreadParams() : 00095 flags(Thread_Default), 00096 prio(ThreadPrio_Normal) 00097 { 00098 }; 00099 ThreadFlags flags; /**< Flags to set on the thread */ 00100 ThreadPriority prio; /**< Priority to set on the thread */ 00101 }; 00102 00103 class IThreadCreator; 00104 00105 /** 00106 * @brief Describes a handle to a thread. 00107 */ 00108 class IThreadHandle 00109 { 00110 public: 00111 /** Virtual destructor */ 00112 virtual ~IThreadHandle() { }; 00113 public: 00114 /** 00115 * @brief Pauses parent thread until this thread completes. 00116 * 00117 * @return True if successful, false otherwise. 00118 */ 00119 virtual bool WaitForThread() =0; 00120 00121 /** 00122 * @brief Destroys the thread handle. This will not necessarily cancel the thread. 00123 */ 00124 virtual void DestroyThis() =0; 00125 00126 /** 00127 * @brief Returns the parent threader. 00128 * 00129 * @return IThreadCreator that created this thread. 00130 */ 00131 virtual IThreadCreator *Parent() =0; 00132 00133 /** 00134 * @brief Returns the thread states. 00135 * 00136 * @param ptparams Pointer to a ThreadParams buffer. 00137 */ 00138 virtual void GetParams(ThreadParams *ptparams) =0; 00139 00140 /** 00141 * @brief Returns the thread priority. 00142 * 00143 * @return Thread priority. 00144 */ 00145 virtual ThreadPriority GetPriority() =0; 00146 00147 /** 00148 * @brief Sets thread priority. 00149 * NOTE: On Linux, this always returns false. 00150 * 00151 * @param prio Thread priority to set. 00152 * @return True if successful, false otherwise. 00153 */ 00154 virtual bool SetPriority(ThreadPriority prio) =0; 00155 00156 /** 00157 * @brief Returns the thread state. 00158 * 00159 * @return Current thread state. 00160 */ 00161 virtual ThreadState GetState() =0; 00162 00163 /** 00164 * @brief Attempts to unpause a paused thread. 00165 * 00166 * @return True on success, false otherwise. 00167 */ 00168 virtual bool Unpause() =0; 00169 }; 00170 00171 /** 00172 * @brief Handles a single thread's execution. 00173 */ 00174 class IThread 00175 { 00176 public: 00177 /** Virtual destructor */ 00178 virtual ~IThread() { }; 00179 public: 00180 /** 00181 * @brief Called when the thread runs (in its own thread). 00182 * 00183 * @param pHandle Pointer to the thread's handle. 00184 */ 00185 virtual void RunThread(IThreadHandle *pHandle) =0; 00186 00187 /** 00188 * @brief Called when the thread terminates. This occurs inside the thread as well. 00189 * 00190 * @param pHandle Pointer to the thread's handle. 00191 * @param cancel True if the thread did not finish, false otherwise. 00192 */ 00193 virtual void OnTerminate(IThreadHandle *pHandle, bool cancel) =0; 00194 }; 00195 00196 00197 /** 00198 * @brief Describes a thread creator 00199 */ 00200 class IThreadCreator 00201 { 00202 public: 00203 /** Virtual Destructor */ 00204 virtual ~IThreadCreator() { }; 00205 public: 00206 /** 00207 * @brief Creates a basic thread. 00208 * 00209 * @param pThread IThread pointer for callbacks. 00210 */ 00211 virtual void MakeThread(IThread *pThread) =0; 00212 00213 /** 00214 * @brief Creates a thread with specific options. 00215 * 00216 * @param pThread IThread pointer for callbacks. 00217 * @param flags Flags for the thread. 00218 * @return IThreadHandle pointer (must be released). 00219 */ 00220 virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0; 00221 00222 /** 00223 * @brief Creates a thread with specific options. 00224 * 00225 * @param pThread IThread pointer for callbacks. 00226 * @param params Extended options for the thread. 00227 * @return IThreadHandle pointer (must be released). 00228 */ 00229 virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0; 00230 00231 /** 00232 * @brief Returns the priority bounds. 00233 * Note: On Linux, the min and max are both Thread_Normal. 00234 * 00235 * @param max Stores the maximum priority level. 00236 * @param min Stores the minimum priority level. 00237 */ 00238 virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0; 00239 }; 00240 00241 /** 00242 * @brief Describes a simple locking mutex. 00243 */ 00244 class IMutex 00245 { 00246 public: 00247 /** Virtual Destructor */ 00248 virtual ~IMutex() { }; 00249 public: 00250 /** 00251 * @brief Attempts to lock, but returns instantly. 00252 * 00253 * @return True if lock was obtained, false otherwise. 00254 */ 00255 virtual bool TryLock() =0; 00256 00257 /** 00258 * @brief Attempts to lock by waiting for release. 00259 */ 00260 virtual void Lock() =0; 00261 00262 /** 00263 * @brief Unlocks the mutex. 00264 */ 00265 virtual void Unlock() =0; 00266 00267 /** 00268 * @brief Destroys the mutex handle. 00269 */ 00270 virtual void DestroyThis() =0; 00271 }; 00272 00273 /** 00274 * @brief Describes a simple "condition variable"/signal lock. 00275 */ 00276 class IEventSignal 00277 { 00278 public: 00279 /** Virtual Destructor */ 00280 virtual ~IEventSignal() { }; 00281 public: 00282 /** 00283 * @brief Waits for a signal. 00284 */ 00285 virtual void Wait() =0; 00286 00287 /** 00288 * @brief Triggers the signal and resets the signal after triggering. 00289 */ 00290 virtual void Signal() =0; 00291 00292 /** 00293 * @brief Frees the signal handle. 00294 */ 00295 virtual void DestroyThis() =0; 00296 }; 00297 00298 /** 00299 * @brief Describes possible worker states 00300 */ 00301 enum WorkerState 00302 { 00303 Worker_Invalid = -3, 00304 Worker_Stopped = -2, 00305 Worker_Paused = -1, 00306 Worker_Running, 00307 }; 00308 00309 /** 00310 * @brief This is a "worker pool." A single thread places tasks in a queue. 00311 * Each IThread is then a task, rather than its own separate thread. 00312 */ 00313 class IThreadWorker : public IThreadCreator 00314 { 00315 public: 00316 /** Virtual Destructor */ 00317 virtual ~IThreadWorker() 00318 { 00319 }; 00320 public: 00321 /** 00322 * @brief Runs one "frame" of the worker. 00323 * 00324 * @return Number of tasks processed. 00325 */ 00326 virtual unsigned int RunFrame() =0; 00327 public: 00328 /** 00329 * @brief Pauses the worker. 00330 * 00331 * @return True on success, false otherwise. 00332 */ 00333 virtual bool Pause() =0; 00334 00335 /** 00336 * @brief Unpauses the worker. 00337 * 00338 * @return True on success, false otherwise. 00339 */ 00340 virtual bool Unpause() =0; 00341 00342 /** 00343 * @brief Starts the worker thread. 00344 * 00345 * @return True on success, false otherwise. 00346 */ 00347 virtual bool Start() =0; 00348 00349 /** 00350 * @brief Stops the worker thread. 00351 * 00352 * @param flush If true, all remaining tasks will be cancelled. 00353 * Otherwise, the threader will wait until the queue is empty. 00354 * @return True on success, false otherwise. 00355 */ 00356 virtual bool Stop(bool flush) =0; 00357 00358 /** 00359 * @brief Returns the status of the worker. 00360 * 00361 * @param numThreads Pointer to store number of threads in the queue. 00362 * @return State of the worker. 00363 */ 00364 virtual WorkerState GetStatus(unsigned int *numThreads) =0; 00365 }; 00366 00367 /** 00368 * @brief Describes thread worker callbacks. 00369 */ 00370 class IThreadWorkerCallbacks 00371 { 00372 public: 00373 /** 00374 * @brief Called when the worker thread is initialized. 00375 * 00376 * @param pWorker Pointer to the worker. 00377 */ 00378 virtual void OnWorkerStart(IThreadWorker *pWorker) 00379 { 00380 } 00381 00382 /** 00383 * @brief Called when the worker thread is cleaning up. 00384 * 00385 * @param pWorker Pointer to the worker. 00386 */ 00387 virtual void OnWorkerStop(IThreadWorker *pWorker) 00388 { 00389 } 00390 }; 00391 00392 /** 00393 * @brief Describes a threading system 00394 */ 00395 class IThreader : public SMInterface, public IThreadCreator 00396 { 00397 public: 00398 virtual const char *GetInterfaceName() 00399 { 00400 return SMINTERFACE_THREADER_NAME; 00401 } 00402 virtual unsigned int GetInterfaceVersion() 00403 { 00404 return SMINTERFACE_THREADER_VERSION; 00405 } 00406 virtual bool IsVersionCompatible(unsigned int version) 00407 { 00408 if (version < 2) 00409 { 00410 return false; 00411 } 00412 return SMInterface::IsVersionCompatible(version); 00413 } 00414 public: 00415 /** 00416 * @brief Creates a mutex (mutual exclusion lock). 00417 * 00418 * @return A new IMutex pointer (must be destroyed). 00419 */ 00420 virtual IMutex *MakeMutex() =0; 00421 00422 /** 00423 * @brief Sleeps the calling thread for a number of milliseconds. 00424 * 00425 * @param ms Millisecond count to sleep. 00426 */ 00427 virtual void ThreadSleep(unsigned int ms) =0; 00428 00429 /** 00430 * @brief Creates a non-signalled event. 00431 * 00432 * @return A new IEventSignal pointer (must be destroyed). 00433 */ 00434 virtual IEventSignal *MakeEventSignal() =0; 00435 00436 /** 00437 * @brief Creates a thread worker. 00438 * 00439 * @param hooks Optional pointer to callback interface. 00440 * @param threaded If true, the worker will be threaded. 00441 * If false, the worker will require manual frame execution. 00442 * @return A new IThreadWorker pointer (must be destroyed). 00443 */ 00444 virtual IThreadWorker *MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded) =0; 00445 00446 /** 00447 * @brief Destroys an IThreadWorker pointer. 00448 * 00449 * @param pWorker IThreadWorker pointer to destroy. 00450 */ 00451 virtual void DestroyWorker(IThreadWorker *pWorker) =0; 00452 }; 00453 }; 00454 00455 #endif //_INCLUDE_SOURCEMOD_THREADER_H
1.5.1