00001 #ifndef GAMMA_THREAD_H_INC
00002 #define GAMMA_THREAD_H_INC
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 namespace gam{
00030
00031 #define GAM_USE_PTHREAD (defined (__APPLE__) || defined (OSX) || defined (__LINUX__) || defined (__UNIX__))
00032 #define GAM_USE_THREADEX (defined(WIN32))
00033
00034 #ifdef GAM_USE_PTHREAD
00035 #include <pthread.h>
00036 #elif GAM_USE_THREADEX
00037 #include <windows.h>
00038 #include <process.h>
00039 #endif
00040
00041 class Thread{
00042 public:
00043
00044 typedef void * (*Function)(void * user);
00045
00046 #ifdef GAM_USE_PTHREAD
00047 typedef pthread_t Handle;
00048 #elif GAM_USE_THREADEX
00049 typedef unsigned long Handle;
00050 #endif
00051
00052 Thread()
00053 : mHandle(0), mJoinOnDestroy(false)
00054 {}
00055
00056 Thread(Function func, void * user = NULL)
00057 : mHandle(0), mJoinOnDestroy(false)
00058 { start(func, user); }
00059
00060 ~Thread(){
00061 if(mJoinOnDestroy) join();
00062 }
00063
00065
00069 bool start(Function func, void * user = NULL);
00070
00072
00078 bool cancel();
00079
00081
00086 bool join();
00087
00088
00090 Thread& joinOnDestroy(bool v){ mJoinOnDestroy=v; return *this; }
00091
00092 protected:
00093 Handle mHandle;
00094 bool mJoinOnDestroy;
00095 };
00096
00097
00098
00099
00100
00101
00102 #ifdef GAM_USE_PTHREAD
00103
00104 inline bool Thread::start(Thread::Function func, void * user){
00105 if(mHandle) return false;
00106 return 0 == pthread_create(&mHandle, NULL, *func, user);
00107 }
00108
00109 inline bool Thread::cancel(){
00110 return 0 == pthread_cancel(mHandle);
00111 }
00112
00113 inline bool Thread::join(){
00114 if(pthread_join(mHandle, NULL) == 0){
00115 mHandle = 0;
00116 return true;
00117 }
00118 return false;
00119 }
00120
00121
00122 #elif GAM_USE_THREADEX
00123
00124 inline bool Thread::start(Thread::Function func, void * user){
00125 if(mHandle) return false;
00126
00127 struct F{
00128 Thread::Function func;
00129 void * user;
00130
00131 static unsigned _stdcall * call(void * user){
00132 F& f = *(F*)user;
00133 f.func(f.userData);
00134 return 0;
00135 }
00136 } f = { func, user };
00137
00138 unsigned thread_id;
00139 mHandle = _beginthreadex(NULL, 0, F::call, &f, 0, &thread_id);
00140 if(mHandle) return true;
00141 return false;
00142 }
00143
00144 inline bool Thread::cancel(){
00145 TerminateThread((HANDLE)mHandle, 0);
00146 return true;
00147 }
00148
00149 inline bool Thread::join(){
00150 long retval = WaitForSingleObject((HANDLE)mHandle, INFINITE);
00151 if(WAIT_OBJECT_0 == retval){
00152 CloseHandle((HANDLE)mHandle);
00153 mHandle = 0;
00154 return true;
00155 }
00156 return false;
00157 }
00158
00159 #endif
00160
00161 }
00162
00163 #endif
00164