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