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