public/IThreader.h
author Nicholas Hastings <skamonkey@gmail.com>
Sun Aug 25 11:01:55 2013 -0400 (2013-08-25)
changeset 4061 fffdcac63ac3
parent 4031 852cf4415d12
permissions -rw-r--r--
Add missing MarkNativeAsOptional calls for cstrike.inc (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@4031
    37
 *
dvander@4031
    38
 * @brief Contains platform independent routines for threading. These tools
dvander@4031
    39
 * should be considered deprecated. Use public/amtl/am-thread-utils.h.
dvander@1084
    40
 */
dvander@1084
    41
dvander@1084
    42
#include <IShareSys.h>
dvander@1084
    43
dvander@1084
    44
#define SMINTERFACE_THREADER_NAME		"IThreader"
asherkin@3704
    45
#define SMINTERFACE_THREADER_VERSION	3
dvander@1084
    46
dvander@1084
    47
namespace SourceMod
dvander@1084
    48
{
dvander@1084
    49
	/**
dvander@1084
    50
	 * @brief Thread creation flags
dvander@1084
    51
	 */
dvander@1084
    52
	enum ThreadFlags
dvander@1084
    53
	{
dvander@1084
    54
		Thread_Default = 0,
dvander@1084
    55
		/**
dvander@1084
    56
		 * @brief Auto-release handle on finish
dvander@1084
    57
		 *
dvander@1084
    58
		 * You are not guaranteed the handle for this is valid after
dvander@1084
    59
		 * calling MakeThread(), so never use it until OnTerminate is called.
dvander@1084
    60
		 */
dvander@1084
    61
		Thread_AutoRelease = 1,
dvander@1084
    62
		/**
dvander@1084
    63
		 * @brief Thread is created "suspended", meaning it is inactive until unpaused.
dvander@1084
    64
		 */
dvander@1084
    65
		Thread_CreateSuspended = 2,
dvander@1084
    66
	};
dvander@1084
    67
dvander@1084
    68
	/**
dvander@1084
    69
	 * @brief Specifies thread priority levels.
dvander@1084
    70
	 */
dvander@1084
    71
	enum ThreadPriority
dvander@1084
    72
	{
dvander@1084
    73
		ThreadPrio_Minimum = -8,
dvander@1084
    74
		ThreadPrio_Low = -3,
dvander@1084
    75
		ThreadPrio_Normal = 0,
dvander@1084
    76
		ThreadPrio_High = 3,
dvander@1084
    77
		ThreadPrio_Maximum = 8,
dvander@1084
    78
	};
dvander@1084
    79
dvander@1084
    80
	/**
dvander@1084
    81
	 * @brief The current state of a thread.
dvander@1084
    82
	 */
dvander@1084
    83
	enum ThreadState
dvander@1084
    84
	{
dvander@1084
    85
		Thread_Running = 0,
dvander@1084
    86
		Thread_Paused = 1,
dvander@1084
    87
		Thread_Done = 2,
dvander@1084
    88
	};
dvander@1084
    89
dvander@1084
    90
	/**
dvander@1084
    91
	 * @brief Thread-specific parameters.
dvander@1084
    92
	 */
dvander@1084
    93
	struct ThreadParams
dvander@1084
    94
	{
dvander@1084
    95
		/** Constructor */
dvander@1084
    96
		ThreadParams() : 
dvander@1084
    97
			flags(Thread_Default), 
dvander@1084
    98
			prio(ThreadPrio_Normal)
dvander@1084
    99
		{
dvander@1084
   100
		};
dvander@1084
   101
		ThreadFlags flags;		/**< Flags to set on the thread */
dvander@1084
   102
		ThreadPriority prio;	/**< Priority to set on the thread */
dvander@1084
   103
	};
dvander@1084
   104
dvander@1084
   105
	class IThreadCreator;
dvander@1084
   106
dvander@1084
   107
	/**
dvander@1084
   108
	 * @brief Describes a handle to a thread.
dvander@1084
   109
	 */
dvander@1084
   110
	class IThreadHandle
dvander@1084
   111
	{
dvander@1084
   112
	public:
dvander@1084
   113
		/** Virtual destructor */
dvander@1084
   114
		virtual ~IThreadHandle() { };
dvander@1084
   115
	public:
dvander@1084
   116
		/**
dvander@1084
   117
		 * @brief Pauses parent thread until this thread completes.
dvander@1084
   118
		 * 
dvander@1084
   119
		 * @return			True if successful, false otherwise.
dvander@1084
   120
		 */
dvander@1084
   121
		virtual bool WaitForThread() =0;
dvander@1084
   122
dvander@1084
   123
		/**
dvander@1084
   124
		 * @brief Destroys the thread handle.  This will not necessarily cancel the thread.
dvander@1084
   125
		 */
dvander@1084
   126
		virtual void DestroyThis() =0;
dvander@1084
   127
dvander@1084
   128
		/**
dvander@1084
   129
		 * @brief Returns the parent threader.
dvander@1084
   130
		 *
dvander@1084
   131
		 * @return			IThreadCreator that created this thread.
dvander@1084
   132
		 */
dvander@1084
   133
		virtual IThreadCreator *Parent() =0;
dvander@1084
   134
dvander@1084
   135
		/**
dvander@1084
   136
		 * @brief Returns the thread states.
dvander@1084
   137
		 *
dvander@1084
   138
		 * @param ptparams	Pointer to a ThreadParams buffer.
dvander@1084
   139
		 */
dvander@1084
   140
		virtual void GetParams(ThreadParams *ptparams) =0;
dvander@1084
   141
dvander@1084
   142
		/**
dvander@1084
   143
		 * @brief Returns the thread priority.
dvander@1084
   144
		 *
dvander@1084
   145
		 * @return			Thread priority.
dvander@1084
   146
		 */
dvander@1084
   147
		virtual ThreadPriority GetPriority() =0;
dvander@1084
   148
dvander@1084
   149
		/**
dvander@1084
   150
		 * @brief Sets thread priority.
dvander@1084
   151
		 * NOTE: On Linux, this always returns false.
dvander@1084
   152
		 *
dvander@1084
   153
		 * @param prio		Thread priority to set.
dvander@1084
   154
		 * @return			True if successful, false otherwise.
dvander@1084
   155
		 */
dvander@1084
   156
		virtual bool SetPriority(ThreadPriority prio) =0;
dvander@1084
   157
dvander@1084
   158
		/**
dvander@1084
   159
		 * @brief Returns the thread state.
dvander@1084
   160
		 * 
dvander@1084
   161
		 * @return			Current thread state.
dvander@1084
   162
		 */
dvander@1084
   163
		virtual ThreadState GetState() =0;
dvander@1084
   164
dvander@1084
   165
		/**
dvander@1084
   166
		 * @brief Attempts to unpause a paused thread.
dvander@1084
   167
		 *
dvander@1084
   168
		 * @return			True on success, false otherwise.
dvander@1084
   169
		 */
dvander@1084
   170
		virtual bool Unpause() =0;
dvander@1084
   171
	};
dvander@1084
   172
dvander@1084
   173
	/**
dvander@1084
   174
	 * @brief Handles a single thread's execution.
dvander@1084
   175
	 */
dvander@1084
   176
	class IThread
dvander@1084
   177
	{
dvander@1084
   178
	public:
dvander@1084
   179
		/** Virtual destructor */
dvander@1084
   180
		virtual ~IThread() { };
dvander@1084
   181
	public:
dvander@1084
   182
		/**
dvander@1084
   183
		 * @brief Called when the thread runs (in its own thread).
dvander@1084
   184
		 *
dvander@1084
   185
		 * @param pHandle		Pointer to the thread's handle.
dvander@1084
   186
		 */
dvander@1084
   187
		virtual void RunThread(IThreadHandle *pHandle) =0;
dvander@1084
   188
dvander@1084
   189
		/**
dvander@1084
   190
		 * @brief Called when the thread terminates.  This occurs inside the thread as well.
dvander@1084
   191
		 *
dvander@1084
   192
		 * @param pHandle		Pointer to the thread's handle.
dvander@1084
   193
		 * @param cancel		True if the thread did not finish, false otherwise.
dvander@1084
   194
		 */
dvander@1084
   195
		virtual void OnTerminate(IThreadHandle *pHandle, bool cancel) =0;
dvander@1084
   196
	};
dvander@1084
   197
dvander@1084
   198
dvander@1084
   199
	/**
dvander@1084
   200
	 * @brief Describes a thread creator
dvander@1084
   201
	 */
dvander@1084
   202
	class IThreadCreator
dvander@1084
   203
	{
dvander@1084
   204
	public:
dvander@1084
   205
		/** Virtual Destructor */
dvander@1084
   206
		virtual ~IThreadCreator() { };
dvander@1084
   207
	public:
dvander@1084
   208
		/**
dvander@1084
   209
		 * @brief Creates a basic thread.
dvander@1084
   210
		 *
dvander@1084
   211
		 * @param pThread		IThread pointer for callbacks.
dvander@1084
   212
		 */
dvander@1084
   213
		virtual void MakeThread(IThread *pThread) =0;
dvander@1084
   214
dvander@1084
   215
		/**
dvander@1084
   216
		 * @brief Creates a thread with specific options.
dvander@1084
   217
		 *
dvander@1084
   218
		 * @param pThread		IThread pointer for callbacks.
dvander@1084
   219
		 * @param flags			Flags for the thread.
dvander@1084
   220
		 * @return				IThreadHandle pointer (must be released).
dvander@1084
   221
		 */
dvander@1084
   222
		virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0;
dvander@1084
   223
dvander@1084
   224
		/**
dvander@1084
   225
		 * @brief Creates a thread with specific options.
dvander@1084
   226
		 *
dvander@1084
   227
		 * @param pThread		IThread pointer for callbacks.
dvander@1084
   228
		 * @param params		Extended options for the thread.
dvander@1084
   229
		 * @return				IThreadHandle pointer (must be released).
dvander@1084
   230
		 */
dvander@1084
   231
		virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0;
dvander@1084
   232
dvander@1084
   233
		/**
dvander@1084
   234
		 * @brief Returns the priority bounds.
dvander@1084
   235
		 * Note: On Linux, the min and max are both Thread_Normal.
dvander@1084
   236
		 *
dvander@1084
   237
		 * @param max			Stores the maximum priority level.
dvander@1084
   238
		 * @param min			Stores the minimum priority level.
dvander@1084
   239
		 */
dvander@1084
   240
		virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0;
dvander@1084
   241
	};
dvander@1084
   242
dvander@1084
   243
	/**
dvander@1084
   244
	 * @brief Describes a simple locking mutex.
dvander@1084
   245
	 */
dvander@1084
   246
	class IMutex
dvander@1084
   247
	{
dvander@1084
   248
	public:
dvander@1084
   249
		/** Virtual Destructor */
dvander@1084
   250
		virtual ~IMutex() { };
dvander@1084
   251
	public:
dvander@1084
   252
		/**
dvander@1084
   253
		 * @brief Attempts to lock, but returns instantly.
dvander@1084
   254
		 *
dvander@1084
   255
		 * @return		True if lock was obtained, false otherwise.
dvander@1084
   256
		 */
dvander@1084
   257
		virtual bool TryLock() =0;
dvander@1084
   258
dvander@1084
   259
		/**
dvander@1084
   260
 		 * @brief Attempts to lock by waiting for release.
dvander@1084
   261
		 */
dvander@1084
   262
		virtual void Lock() =0;
dvander@1084
   263
dvander@1084
   264
		/**
dvander@1084
   265
		 * @brief Unlocks the mutex.
dvander@1084
   266
		 */
dvander@1084
   267
		virtual void Unlock() =0;
dvander@1084
   268
dvander@1084
   269
		/**
dvander@1084
   270
		 * @brief Destroys the mutex handle.
dvander@1084
   271
		 */
dvander@1084
   272
		virtual void DestroyThis() =0;
dvander@1084
   273
	};
dvander@1084
   274
dvander@1084
   275
	/**
dvander@1084
   276
	 * @brief Describes a simple "condition variable"/signal lock.
dvander@1084
   277
	 */
dvander@1084
   278
	class IEventSignal
dvander@1084
   279
	{
dvander@1084
   280
	public:
dvander@1084
   281
		/** Virtual Destructor */
dvander@1084
   282
		virtual ~IEventSignal() { };
dvander@1084
   283
	public:
dvander@1084
   284
		/**
dvander@1084
   285
		 * @brief Waits for a signal.
dvander@1084
   286
		 */
dvander@1084
   287
		virtual void Wait() =0;
dvander@1084
   288
dvander@1084
   289
		/** 
dvander@1084
   290
		 * @brief Triggers the signal and resets the signal after triggering.
dvander@1084
   291
		 */
dvander@1084
   292
		virtual void Signal() =0;
dvander@1084
   293
dvander@1084
   294
		/**
dvander@1084
   295
		 * @brief Frees the signal handle.
dvander@1084
   296
		 */
dvander@1084
   297
		virtual void DestroyThis() =0;
dvander@1084
   298
	};
dvander@1084
   299
dvander@1084
   300
	/**
dvander@1084
   301
	 * @brief Describes possible worker states
dvander@1084
   302
	 */
dvander@1084
   303
	enum WorkerState
dvander@1084
   304
	{
dvander@1084
   305
		Worker_Invalid = -3,
dvander@1084
   306
		Worker_Stopped = -2,
dvander@1084
   307
		Worker_Paused = -1,
dvander@1084
   308
		Worker_Running,
dvander@1084
   309
	};
dvander@1084
   310
dvander@1084
   311
	/**
dvander@1084
   312
	 * @brief This is a "worker pool."  A single thread places tasks in a queue.
dvander@1084
   313
	 * Each IThread is then a task, rather than its own separate thread.
dvander@1084
   314
	 */
dvander@1084
   315
	class IThreadWorker : public IThreadCreator
dvander@1084
   316
	{
dvander@1084
   317
	public:
dvander@1084
   318
		/** Virtual Destructor */
dvander@1084
   319
		virtual ~IThreadWorker()
dvander@1084
   320
		{
dvander@1084
   321
		};
dvander@1084
   322
	public:
dvander@1084
   323
		/**
dvander@1084
   324
		 * @brief Runs one "frame" of the worker.
dvander@1084
   325
		 *
dvander@1084
   326
		 * @return			Number of tasks processed.
dvander@1084
   327
		 */
dvander@1084
   328
		virtual unsigned int RunFrame() =0;
dvander@1084
   329
	public:
dvander@1084
   330
		/**
dvander@1084
   331
		 * @brief Pauses the worker.
dvander@1084
   332
		 *
dvander@1084
   333
		 * @return			True on success, false otherwise.
dvander@1084
   334
		 */
dvander@1084
   335
		virtual bool Pause() =0;
dvander@1084
   336
dvander@1084
   337
		/**
dvander@1084
   338
		 * @brief Unpauses the worker.
dvander@1084
   339
		 *
dvander@1084
   340
		 * @return			True on success, false otherwise.
dvander@1084
   341
		 */
dvander@1084
   342
		virtual bool Unpause() =0;
dvander@1084
   343
dvander@1084
   344
		/** 
dvander@1084
   345
		 * @brief Starts the worker thread.
dvander@1084
   346
		 *
dvander@1084
   347
		 * @return			True on success, false otherwise.
dvander@1084
   348
		 */
dvander@1084
   349
		virtual bool Start() =0;
dvander@1084
   350
dvander@1084
   351
		/**
dvander@1084
   352
		 * @brief Stops the worker thread.
dvander@1084
   353
		 *
dvander@1084
   354
		 * @param flush		If true, all remaining tasks will be cancelled.
dvander@1084
   355
		 *					Otherwise, the threader will wait until the queue is empty.
dvander@1084
   356
		 * @return			True on success, false otherwise.
dvander@1084
   357
		 */
dvander@1084
   358
		virtual bool Stop(bool flush) =0;
dvander@1084
   359
dvander@1084
   360
		/**
dvander@1084
   361
		 * @brief Returns the status of the worker.
dvander@1084
   362
		 *
dvander@1084
   363
		 * @param numThreads	Pointer to store number of threads in the queue.
dvander@1084
   364
		 * @return				State of the worker.
dvander@1084
   365
		 */
dvander@1084
   366
		virtual WorkerState GetStatus(unsigned int *numThreads) =0;
asherkin@3704
   367
asherkin@3704
   368
		/**
asherkin@3704
   369
		 * @brief Sets the number of threads to run per frame.
asherkin@3704
   370
		 * Default value is 1 thread per frame.
asherkin@3704
   371
		 *
asherkin@3704
   372
		 * @param threads	Number of threads to run per frame.
asherkin@3704
   373
		 */
asherkin@3704
   374
		virtual void SetMaxThreadsPerFrame(unsigned int threads) =0;
asherkin@3704
   375
asherkin@3704
   376
		/**
asherkin@3704
   377
		 * @brief For threaded workers, the think time of a frame.
asherkin@3704
   378
		 * Has no effect for non-threaded workers.
asherkin@3704
   379
		 * Default value is 50ms.
asherkin@3704
   380
		 *
asherkin@3704
   381
		 * @param thinktime	Number of ms to sleep between frame execution.
asherkin@3704
   382
		 */
asherkin@3704
   383
		virtual void SetThinkTimePerFrame(unsigned int thinktime) =0;
dvander@1084
   384
	};
dvander@1084
   385
dvander@1084
   386
	/**
dvander@1090
   387
	 * @brief Describes thread worker callbacks.
dvander@1090
   388
	 */
dvander@1090
   389
	class IThreadWorkerCallbacks
dvander@1090
   390
	{
dvander@1090
   391
	public:
dvander@1090
   392
		/**
dvander@1090
   393
		 * @brief Called when the worker thread is initialized.
dvander@1090
   394
		 *
dvander@1090
   395
		 * @param pWorker		Pointer to the worker.
dvander@1090
   396
		 */
dvander@1090
   397
		virtual void OnWorkerStart(IThreadWorker *pWorker)
dvander@1090
   398
		{
dvander@1090
   399
		}
dvander@1090
   400
dvander@1090
   401
		/**
dvander@1090
   402
		 * @brief Called when the worker thread is cleaning up.
dvander@1090
   403
		 *
dvander@1090
   404
		 * @param pWorker		Pointer to the worker.
dvander@1090
   405
		 */
dvander@1090
   406
		virtual void OnWorkerStop(IThreadWorker *pWorker)
dvander@1090
   407
		{
dvander@1090
   408
		}
dvander@1090
   409
	};
dvander@1090
   410
dvander@1090
   411
	/**
dvander@1084
   412
	 * @brief Describes a threading system
dvander@1084
   413
	 */
dvander@1084
   414
	class IThreader : public SMInterface, public IThreadCreator
dvander@1084
   415
	{
dvander@1084
   416
	public:
dvander@1084
   417
		virtual const char *GetInterfaceName()
dvander@1084
   418
		{
dvander@1084
   419
			return SMINTERFACE_THREADER_NAME;
dvander@1084
   420
		}
dvander@1084
   421
		virtual unsigned int GetInterfaceVersion()
dvander@1084
   422
		{
dvander@1084
   423
			return SMINTERFACE_THREADER_VERSION;
dvander@1084
   424
		}
dvander@1090
   425
		virtual bool IsVersionCompatible(unsigned int version)
dvander@1090
   426
		{
dvander@1090
   427
			if (version < 2)
dvander@1090
   428
			{
dvander@1090
   429
				return false;
dvander@1090
   430
			}
dvander@1090
   431
			return SMInterface::IsVersionCompatible(version);
dvander@1090
   432
		}
dvander@1084
   433
	public:
dvander@1084
   434
		/**
dvander@1084
   435
		 * @brief Creates a mutex (mutual exclusion lock).
dvander@1084
   436
		 *
dvander@1084
   437
		 * @return			A new IMutex pointer (must be destroyed).
dvander@1084
   438
		 */
dvander@1084
   439
		virtual IMutex *MakeMutex() =0;
dvander@1084
   440
dvander@1084
   441
		/**
dvander@1084
   442
		 * @brief Sleeps the calling thread for a number of milliseconds.
dvander@1084
   443
		 *
dvander@1084
   444
		 * @param ms		Millisecond count to sleep.
dvander@1084
   445
		 */
dvander@1084
   446
		virtual void ThreadSleep(unsigned int ms) =0;
dvander@1084
   447
dvander@1084
   448
		/**
dvander@1084
   449
		 * @brief Creates a non-signalled event.
dvander@1084
   450
		 *
dvander@1084
   451
		 * @return			A new IEventSignal pointer (must be destroyed).
dvander@1084
   452
		 */
dvander@1084
   453
		virtual IEventSignal *MakeEventSignal() =0;
dvander@1084
   454
dvander@1084
   455
		/**
dvander@1084
   456
		 * @brief Creates a thread worker.
dvander@1084
   457
		 *
dvander@1090
   458
		 * @param hooks		Optional pointer to callback interface.
dvander@1084
   459
		 * @param threaded	If true, the worker will be threaded.
dvander@1084
   460
		 *					If false, the worker will require manual frame execution.
dvander@1084
   461
		 * @return			A new IThreadWorker pointer (must be destroyed).
dvander@1084
   462
		 */
dvander@1090
   463
		virtual IThreadWorker *MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded) =0;
dvander@1084
   464
dvander@1084
   465
		/**
dvander@1084
   466
		 * @brief Destroys an IThreadWorker pointer.
dvander@1084
   467
		 *
dvander@1084
   468
		 * @param pWorker	IThreadWorker pointer to destroy.
dvander@1084
   469
		 */
dvander@1084
   470
		virtual void DestroyWorker(IThreadWorker *pWorker) =0;
dvander@1084
   471
	};
dvander@1084
   472
};
dvander@1084
   473
dvander@1084
   474
#endif //_INCLUDE_SOURCEMOD_THREADER_H