public/IThreader.h
author David Anderson <dvander@alliedmods.net>
Thu Jul 12 16:57:26 2007 +0000 (2007-07-12)
changeset 1090 5c54e353c019
parent 1084 241c1b9b4048
child 1226 478550a4d5ec
permissions -rw-r--r--
- added callback functionality to IThreadWorker
- added exposure of IThreader to sample sdk
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod, Copyright (C) 2004-2007 AlliedModders LLC. 
     5  * All rights reserved.
     6  * ===============================================================
     7  *
     8  *  This file is part of the SourceMod/SourcePawn SDK.  This file may only be 
     9  * used or modified under the Terms and Conditions of its License Agreement, 
    10  * which is found in public/licenses/LICENSE.txt.  As of this notice, derivative 
    11  * works must be licensed under the GNU General Public License (version 2 or 
    12  * greater).  A copy of the GPL is included under public/licenses/GPL.txt.
    13  * 
    14  * To view the latest information, see: http://www.sourcemod.net/license.php
    15  *
    16  * Version: $Id$
    17  */
    18 
    19 #ifndef _INCLUDE_SOURCEMOD_THREADER_H
    20 #define _INCLUDE_SOURCEMOD_THREADER_H
    21 
    22 /**
    23  * @file IThreader.h
    24  * @brief Contains platform independent routines for threading.
    25  */
    26 
    27 #include <IShareSys.h>
    28 
    29 #define SMINTERFACE_THREADER_NAME		"IThreader"
    30 #define SMINTERFACE_THREADER_VERSION	2
    31 
    32 namespace SourceMod
    33 {
    34 	/**
    35 	 * @brief Thread creation flags
    36 	 */
    37 	enum ThreadFlags
    38 	{
    39 		Thread_Default = 0,
    40 		/**
    41 		 * @brief Auto-release handle on finish
    42 		 *
    43 		 * You are not guaranteed the handle for this is valid after
    44 		 * calling MakeThread(), so never use it until OnTerminate is called.
    45 		 */
    46 		Thread_AutoRelease = 1,
    47 		/**
    48 		 * @brief Thread is created "suspended", meaning it is inactive until unpaused.
    49 		 */
    50 		Thread_CreateSuspended = 2,
    51 	};
    52 
    53 	/**
    54 	 * @brief Specifies thread priority levels.
    55 	 */
    56 	enum ThreadPriority
    57 	{
    58 		ThreadPrio_Minimum = -8,
    59 		ThreadPrio_Low = -3,
    60 		ThreadPrio_Normal = 0,
    61 		ThreadPrio_High = 3,
    62 		ThreadPrio_Maximum = 8,
    63 	};
    64 
    65 	/**
    66 	 * @brief The current state of a thread.
    67 	 */
    68 	enum ThreadState
    69 	{
    70 		Thread_Running = 0,
    71 		Thread_Paused = 1,
    72 		Thread_Done = 2,
    73 	};
    74 
    75 	/**
    76 	 * @brief Thread-specific parameters.
    77 	 */
    78 	struct ThreadParams
    79 	{
    80 		/** Constructor */
    81 		ThreadParams() : 
    82 			flags(Thread_Default), 
    83 			prio(ThreadPrio_Normal)
    84 		{
    85 		};
    86 		ThreadFlags flags;		/**< Flags to set on the thread */
    87 		ThreadPriority prio;	/**< Priority to set on the thread */
    88 	};
    89 
    90 	class IThreadCreator;
    91 
    92 	/**
    93 	 * @brief Describes a handle to a thread.
    94 	 */
    95 	class IThreadHandle
    96 	{
    97 	public:
    98 		/** Virtual destructor */
    99 		virtual ~IThreadHandle() { };
   100 	public:
   101 		/**
   102 		 * @brief Pauses parent thread until this thread completes.
   103 		 * 
   104 		 * @return			True if successful, false otherwise.
   105 		 */
   106 		virtual bool WaitForThread() =0;
   107 
   108 		/**
   109 		 * @brief Destroys the thread handle.  This will not necessarily cancel the thread.
   110 		 */
   111 		virtual void DestroyThis() =0;
   112 
   113 		/**
   114 		 * @brief Returns the parent threader.
   115 		 *
   116 		 * @return			IThreadCreator that created this thread.
   117 		 */
   118 		virtual IThreadCreator *Parent() =0;
   119 
   120 		/**
   121 		 * @brief Returns the thread states.
   122 		 *
   123 		 * @param ptparams	Pointer to a ThreadParams buffer.
   124 		 */
   125 		virtual void GetParams(ThreadParams *ptparams) =0;
   126 
   127 		/**
   128 		 * @brief Returns the thread priority.
   129 		 *
   130 		 * @return			Thread priority.
   131 		 */
   132 		virtual ThreadPriority GetPriority() =0;
   133 
   134 		/**
   135 		 * @brief Sets thread priority.
   136 		 * NOTE: On Linux, this always returns false.
   137 		 *
   138 		 * @param prio		Thread priority to set.
   139 		 * @return			True if successful, false otherwise.
   140 		 */
   141 		virtual bool SetPriority(ThreadPriority prio) =0;
   142 
   143 		/**
   144 		 * @brief Returns the thread state.
   145 		 * 
   146 		 * @return			Current thread state.
   147 		 */
   148 		virtual ThreadState GetState() =0;
   149 
   150 		/**
   151 		 * @brief Attempts to unpause a paused thread.
   152 		 *
   153 		 * @return			True on success, false otherwise.
   154 		 */
   155 		virtual bool Unpause() =0;
   156 	};
   157 
   158 	/**
   159 	 * @brief Handles a single thread's execution.
   160 	 */
   161 	class IThread
   162 	{
   163 	public:
   164 		/** Virtual destructor */
   165 		virtual ~IThread() { };
   166 	public:
   167 		/**
   168 		 * @brief Called when the thread runs (in its own thread).
   169 		 *
   170 		 * @param pHandle		Pointer to the thread's handle.
   171 		 */
   172 		virtual void RunThread(IThreadHandle *pHandle) =0;
   173 
   174 		/**
   175 		 * @brief Called when the thread terminates.  This occurs inside the thread as well.
   176 		 *
   177 		 * @param pHandle		Pointer to the thread's handle.
   178 		 * @param cancel		True if the thread did not finish, false otherwise.
   179 		 */
   180 		virtual void OnTerminate(IThreadHandle *pHandle, bool cancel) =0;
   181 	};
   182 
   183 
   184 	/**
   185 	 * @brief Describes a thread creator
   186 	 */
   187 	class IThreadCreator
   188 	{
   189 	public:
   190 		/** Virtual Destructor */
   191 		virtual ~IThreadCreator() { };
   192 	public:
   193 		/**
   194 		 * @brief Creates a basic thread.
   195 		 *
   196 		 * @param pThread		IThread pointer for callbacks.
   197 		 */
   198 		virtual void MakeThread(IThread *pThread) =0;
   199 
   200 		/**
   201 		 * @brief Creates a thread with specific options.
   202 		 *
   203 		 * @param pThread		IThread pointer for callbacks.
   204 		 * @param flags			Flags for the thread.
   205 		 * @return				IThreadHandle pointer (must be released).
   206 		 */
   207 		virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0;
   208 
   209 		/**
   210 		 * @brief Creates a thread with specific options.
   211 		 *
   212 		 * @param pThread		IThread pointer for callbacks.
   213 		 * @param params		Extended options for the thread.
   214 		 * @return				IThreadHandle pointer (must be released).
   215 		 */
   216 		virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0;
   217 
   218 		/**
   219 		 * @brief Returns the priority bounds.
   220 		 * Note: On Linux, the min and max are both Thread_Normal.
   221 		 *
   222 		 * @param max			Stores the maximum priority level.
   223 		 * @param min			Stores the minimum priority level.
   224 		 */
   225 		virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0;
   226 	};
   227 
   228 	/**
   229 	 * @brief Describes a simple locking mutex.
   230 	 */
   231 	class IMutex
   232 	{
   233 	public:
   234 		/** Virtual Destructor */
   235 		virtual ~IMutex() { };
   236 	public:
   237 		/**
   238 		 * @brief Attempts to lock, but returns instantly.
   239 		 *
   240 		 * @return		True if lock was obtained, false otherwise.
   241 		 */
   242 		virtual bool TryLock() =0;
   243 
   244 		/**
   245  		 * @brief Attempts to lock by waiting for release.
   246 		 */
   247 		virtual void Lock() =0;
   248 
   249 		/**
   250 		 * @brief Unlocks the mutex.
   251 		 */
   252 		virtual void Unlock() =0;
   253 
   254 		/**
   255 		 * @brief Destroys the mutex handle.
   256 		 */
   257 		virtual void DestroyThis() =0;
   258 	};
   259 
   260 	/**
   261 	 * @brief Describes a simple "condition variable"/signal lock.
   262 	 */
   263 	class IEventSignal
   264 	{
   265 	public:
   266 		/** Virtual Destructor */
   267 		virtual ~IEventSignal() { };
   268 	public:
   269 		/**
   270 		 * @brief Waits for a signal.
   271 		 */
   272 		virtual void Wait() =0;
   273 
   274 		/** 
   275 		 * @brief Triggers the signal and resets the signal after triggering.
   276 		 */
   277 		virtual void Signal() =0;
   278 
   279 		/**
   280 		 * @brief Frees the signal handle.
   281 		 */
   282 		virtual void DestroyThis() =0;
   283 	};
   284 
   285 	/**
   286 	 * @brief Describes possible worker states
   287 	 */
   288 	enum WorkerState
   289 	{
   290 		Worker_Invalid = -3,
   291 		Worker_Stopped = -2,
   292 		Worker_Paused = -1,
   293 		Worker_Running,
   294 	};
   295 
   296 	/**
   297 	 * @brief This is a "worker pool."  A single thread places tasks in a queue.
   298 	 * Each IThread is then a task, rather than its own separate thread.
   299 	 */
   300 	class IThreadWorker : public IThreadCreator
   301 	{
   302 	public:
   303 		/** Virtual Destructor */
   304 		virtual ~IThreadWorker()
   305 		{
   306 		};
   307 	public:
   308 		/**
   309 		 * @brief Runs one "frame" of the worker.
   310 		 *
   311 		 * @return			Number of tasks processed.
   312 		 */
   313 		virtual unsigned int RunFrame() =0;
   314 	public:
   315 		/**
   316 		 * @brief Pauses the worker.
   317 		 *
   318 		 * @return			True on success, false otherwise.
   319 		 */
   320 		virtual bool Pause() =0;
   321 
   322 		/**
   323 		 * @brief Unpauses the worker.
   324 		 *
   325 		 * @return			True on success, false otherwise.
   326 		 */
   327 		virtual bool Unpause() =0;
   328 
   329 		/** 
   330 		 * @brief Starts the worker thread.
   331 		 *
   332 		 * @return			True on success, false otherwise.
   333 		 */
   334 		virtual bool Start() =0;
   335 
   336 		/**
   337 		 * @brief Stops the worker thread.
   338 		 *
   339 		 * @param flush		If true, all remaining tasks will be cancelled.
   340 		 *					Otherwise, the threader will wait until the queue is empty.
   341 		 * @return			True on success, false otherwise.
   342 		 */
   343 		virtual bool Stop(bool flush) =0;
   344 
   345 		/**
   346 		 * @brief Returns the status of the worker.
   347 		 *
   348 		 * @param numThreads	Pointer to store number of threads in the queue.
   349 		 * @return				State of the worker.
   350 		 */
   351 		virtual WorkerState GetStatus(unsigned int *numThreads) =0;
   352 	};
   353 
   354 	/**
   355 	 * @brief Describes thread worker callbacks.
   356 	 */
   357 	class IThreadWorkerCallbacks
   358 	{
   359 	public:
   360 		/**
   361 		 * @brief Called when the worker thread is initialized.
   362 		 *
   363 		 * @param pWorker		Pointer to the worker.
   364 		 */
   365 		virtual void OnWorkerStart(IThreadWorker *pWorker)
   366 		{
   367 		}
   368 
   369 		/**
   370 		 * @brief Called when the worker thread is cleaning up.
   371 		 *
   372 		 * @param pWorker		Pointer to the worker.
   373 		 */
   374 		virtual void OnWorkerStop(IThreadWorker *pWorker)
   375 		{
   376 		}
   377 	};
   378 
   379 	/**
   380 	 * @brief Describes a threading system
   381 	 */
   382 	class IThreader : public SMInterface, public IThreadCreator
   383 	{
   384 	public:
   385 		virtual const char *GetInterfaceName()
   386 		{
   387 			return SMINTERFACE_THREADER_NAME;
   388 		}
   389 		virtual unsigned int GetInterfaceVersion()
   390 		{
   391 			return SMINTERFACE_THREADER_VERSION;
   392 		}
   393 		virtual bool IsVersionCompatible(unsigned int version)
   394 		{
   395 			if (version < 2)
   396 			{
   397 				return false;
   398 			}
   399 			return SMInterface::IsVersionCompatible(version);
   400 		}
   401 	public:
   402 		/**
   403 		 * @brief Creates a mutex (mutual exclusion lock).
   404 		 *
   405 		 * @return			A new IMutex pointer (must be destroyed).
   406 		 */
   407 		virtual IMutex *MakeMutex() =0;
   408 
   409 		/**
   410 		 * @brief Sleeps the calling thread for a number of milliseconds.
   411 		 *
   412 		 * @param ms		Millisecond count to sleep.
   413 		 */
   414 		virtual void ThreadSleep(unsigned int ms) =0;
   415 
   416 		/**
   417 		 * @brief Creates a non-signalled event.
   418 		 *
   419 		 * @return			A new IEventSignal pointer (must be destroyed).
   420 		 */
   421 		virtual IEventSignal *MakeEventSignal() =0;
   422 
   423 		/**
   424 		 * @brief Creates a thread worker.
   425 		 *
   426 		 * @param hooks		Optional pointer to callback interface.
   427 		 * @param threaded	If true, the worker will be threaded.
   428 		 *					If false, the worker will require manual frame execution.
   429 		 * @return			A new IThreadWorker pointer (must be destroyed).
   430 		 */
   431 		virtual IThreadWorker *MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded) =0;
   432 
   433 		/**
   434 		 * @brief Destroys an IThreadWorker pointer.
   435 		 *
   436 		 * @param pWorker	IThreadWorker pointer to destroy.
   437 		 */
   438 		virtual void DestroyWorker(IThreadWorker *pWorker) =0;
   439 	};
   440 };
   441 
   442 #endif //_INCLUDE_SOURCEMOD_THREADER_H