00001 #ifndef __THREAD_H__ 00002 #define __THREAD_H__ 00003 00004 typedef int (*THREAD_START)( void *pArg ); 00005 00006 // SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data); 00007 // Uint32 SDL_GetThreadID(SDL_Thread *thread); 00008 00009 00010 class Thread { 00011 protected: 00012 00013 SDL_Thread *tid; // The Thread ID 00014 00015 THREAD_START threadFunc; 00016 00017 long threadReturnCode; 00018 void *arg; 00019 00020 public: 00021 /* 00022 * Info: Default Constructor 00023 */ 00024 Thread( void ) 00025 : tid( 0 ) , threadReturnCode( -1 ) , arg( 0 ) 00026 { 00027 threadFunc = (THREAD_START)Thread::EntryPoint; // Can call Detach() also. 00028 } 00029 00030 /* 00031 * Info: Plug Constructor 00032 * 00033 * Use this to migrate/port existing worker threads to objects immediately 00034 * Although you lose the benefits of ThreadCTOR and ThreadDTOR. 00035 */ 00036 Thread( THREAD_START aExternalRoutine ) 00037 : tid( 0 ) , threadReturnCode( -1 ) , arg( 0 ) 00038 { 00039 Attach( aExternalRoutine ); 00040 } 00041 00042 /* 00043 * Info: Default Destructor 00044 * 00045 * I think it is wise to destroy the thread even if it is running, 00046 * when the main thread reaches here. 00047 */ 00048 ~Thread() 00049 { 00050 if( tid ) 00051 SDL_KillThread( tid ); 00052 // if ( m_ThreadCtx.m_hThread ) Stop(true); 00053 } 00054 00055 /* 00056 * Info: return the thread handle.... 00057 */ 00058 SDL_Thread *GetHandle( void ) { return tid; } 00059 00060 /* 00061 * Info: Starts the thread. 00062 * 00063 * This function starts the thread pointed by m_pThreadFunc with default attributes 00064 */ 00065 const bool Start( void* aArg = NULL ) 00066 { 00067 tid = SDL_CreateThread( threadFunc , this ); // CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID); 00068 threadReturnCode = 0; 00069 arg = aArg; 00070 return tid != 0; 00071 } 00072 00073 void Stop( void ) 00074 { 00075 if( tid ) 00076 SDL_KillThread( tid ); 00077 tid = 0; 00078 } 00079 /* 00080 * Info: Starts the thread. 00081 * 00082 * This function starts the thread pointed by m_pThreadFunc with default attributes 00083 */ 00084 long GetExitCode() const 00085 { 00086 return threadReturnCode; 00087 } 00088 00089 int Wait( void ) 00090 { 00091 SDL_WaitThread( GetHandle() , (int *)&threadReturnCode ); 00092 tid = 0; 00093 return GetExitCode(); 00094 00095 } 00096 /* 00097 * Info: Attaches a Thread Function 00098 * Used primarily for porting but can serve in developing generic thread objects 00099 */ 00100 void Attach( THREAD_START lpThreadFunc ){ threadFunc = lpThreadFunc; } 00101 00102 /* 00103 * Info: Detaches the Attached Thread Function 00104 * 00105 * Detaches the Attached Thread Function, If any. 00106 * by resetting the thread function pointer to EntryPoint1 00107 */ 00108 void Detach( void ){ threadFunc = Thread::EntryPoint; } 00109 00110 protected: 00111 00112 /* 00113 * Info: DONT override this method. 00114 * 00115 * This function is like a standard template. 00116 * Override if you are sure of what you are doing. 00117 */ 00118 #ifndef WIN32 00119 # define __cdecl 00120 #endif 00121 static int __cdecl EntryPoint( void *pArg) 00122 { 00123 Thread *pParent = reinterpret_cast<Thread*>( pArg ); 00124 00125 pParent->ThreadCtor(); 00126 00127 pParent->threadReturnCode = pParent->Run( pParent->arg ); 00128 00129 pParent->ThreadDtor(); 00130 00131 return 0; 00132 } 00133 00134 public: 00135 00136 /* 00137 * Info: Override this method. 00138 * 00139 * This function should contain the body/code of your thread. 00140 * Notice the signature is similar to that of any worker thread function 00141 * except for the calling convention. 00142 */ 00143 virtual long Run( void * /* arg */ ) { return 0; } 00144 00145 /* 00146 * Info: Constructor-like function. 00147 * 00148 * Will be called by EntryPoint before executing the thread body. 00149 * Override this function to provide your extra initialization. 00150 * 00151 * NOTE: do not confuse it with the classes constructor 00152 */ 00153 virtual void ThreadCtor(){ } 00154 00155 /* 00156 * Info: Destructor-like function. 00157 * 00158 * Will be called by EntryPoint after executing the thread body. 00159 * Override this function to provide your extra destruction. 00160 * 00161 * NOTE: do not confuse it with the classes constructor 00162 */ 00163 virtual void ThreadDtor() { tid = 0; } 00164 00165 }; 00166 00167 #endif //__THREAD_H__