00001
00002
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
00030
00031
00032
00033
00034
00036 #ifndef _U_Thread_Win32_
00037 #define _U_Thread_Win32_
00038
00039 #include "rtabmap/utilite/Win32/UWin32.h"
00040 #include "rtabmap/utilite/USemaphore.h"
00041 #include "rtabmap/utilite/UMutex.h"
00042
00043 inline void uSleep(unsigned int ms)
00044 {
00045 Sleep(ms);
00046 }
00047
00048 #ifdef _CRT_
00049 # include <process.h>
00050 # ifdef _USE_BEGINTHREAD
00051 # define THREAD_CALL __cdecl
00052 # define THREAD_HANDLE uintptr_t
00053 # define THREAD_RET_T void
00054 # define CREATE_THREAD_FAILED (-1L)
00055 # define CREATE_THREAD_ERROR (errno)
00056 # define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthread((void (__cdecl *)(void *))_F,_S,(void *)_P))
00057 # define EXIT_THREAD _endthread()
00058 # define CLOSE_HANDLE(x) 1
00059 # define THREAD_RETURN(x) return
00060 # else
00061 # define THREAD_CALL WINAPI
00062 # define THREAD_HANDLE HANDLE
00063 # define THREAD_RET_T UINT
00064 # define CREATE_THREAD_FAILED (0L)
00065 # define CREATE_THREAD_ERROR (errno)
00066 # define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthreadex(0,_S,(UINT (WINAPI *)(void *))_F,(void *)_P,0,0))
00067 # define EXIT_THREAD _endthreadex(0)
00068 # define CLOSE_HANDLE(x) CloseHandle(x)
00069 # define THREAD_RETURN(x) return(x)
00070 # endif
00071 #else
00072 # define THREAD_CALL WINAPI
00073 # define THREAD_HANDLE HANDLE
00074 # define THREAD_RET_T DWORD
00075 # define CREATE_THREAD_FAILED (0L)
00076 # define CREATE_THREAD_ERROR GetLastError()
00077 # define CREATE_THREAD(_S,_F,_P) ((Handle)CreateThread(0,_S,(DWORD (WINAPI *)(void *))_F,(void *)_P,0,0))
00078 # define CREATE_THREAD2(_S,_F,_P,_ID) ((Handle)CreateThread(0,_S,(DWORD (WINAPI *)(void *))_F,(void *)_P,0,_ID))
00079 # define EXIT_THREAD ExitThread(0)
00080 # define CLOSE_HANDLE(x) CloseHandle(x)
00081 # define THREAD_RETURN(x) return(x)
00082 #endif
00083
00084 #define InvalidHandle 0
00085
00086 template
00087 <
00088 typename Thread_T
00089 >
00090 class UTILITE_EXP UThreadC
00091 {
00092 private:
00093 struct Instance;
00094
00095 public:
00096 typedef Thread_T & Thread_R;
00097 typedef const Thread_T & Thread_C_R;
00098
00099 typedef THREAD_HANDLE Handle;
00100 typedef void (* Handler)( Thread_R );
00101
00102 protected:
00103 UThreadC() {}
00104
00105 virtual void ThreadMain( Thread_R ) = 0;
00106
00107 static void Exit()
00108 { EXIT_THREAD; }
00109
00110 static void TestCancel()
00111 { Sleep(0); }
00112
00113 static int Self()
00114 {
00115 Handle Hnd = InvalidHandle;
00116 DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),(LPHANDLE)&Hnd,NULL,0,NULL);
00117 return Hnd;
00118
00119
00120
00121 }
00122
00123 public:
00124
00125 static int Create(
00126 const Handler & Function,
00127 Thread_C_R Param,
00128 Handle * const & H = 0,
00129 const bool & CreateDetached = false,
00130 const unsigned int & StackSize = 0,
00131 const bool & CancelEnable = false,
00132 const bool & CancelAsync = false
00133 )
00134 {
00135 M_Create().lock();
00136
00137 Instance I(Param,0,Function);
00138
00139 Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I));
00140
00141 if ( Hnd == CREATE_THREAD_FAILED )
00142 {
00143 if ( H ) *H = InvalidHandle;
00144 M_Create().unlock();
00145 return CREATE_THREAD_ERROR;
00146 }
00147
00148 if ( H ) *H = Hnd;
00149
00150 S_Create().Wait();
00151 M_Create().unlock();
00152
00153 if ( CreateDetached ) CLOSE_HANDLE(Hnd);
00154 return 0;
00155 }
00156
00157 int Create(
00158 Thread_C_R Param,
00159 Handle * const & H = 0,
00160 const bool & CreateDetached = false,
00161 const unsigned int & StackSize = 0,
00162 const bool & CancelEnable = false,
00163 const bool & CancelAsync = false
00164 ) const
00165 {
00166 M_Create().lock();
00167
00168 Instance I(Param,const_cast<UThreadC *>(this));
00169
00170 Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I));
00171
00172 if ( Hnd == CREATE_THREAD_FAILED )
00173 {
00174 if ( H ) *H = InvalidHandle;
00175 M_Create().unlock();
00176 return CREATE_THREAD_ERROR;
00177 }
00178
00179 if ( H ) *H = Hnd;
00180
00181 S_Create().Wait();
00182 M_Create().unlock();
00183
00184 if ( CreateDetached ) CLOSE_HANDLE(Hnd);
00185 return 0;
00186 }
00187
00188 static int Join( const Handle &H )
00189 {
00190 DWORD R = WaitForSingleObject((HANDLE)H,INFINITE);
00191
00192 if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) )
00193 {
00194 CLOSE_HANDLE(H);
00195 return 0;
00196 }
00197
00198 if ( R == WAIT_TIMEOUT ) return EAGAIN;
00199 return EINVAL;
00200 }
00201
00202 static int Kill( const Handle &H )
00203 { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; }
00204
00205 static int Detach( const Handle &H )
00206 { return (CLOSE_HANDLE(H)?0:EINVAL); }
00207
00208 private:
00209
00210 static const UMutex &M_Create() { static UMutex M; return M; }
00211 static const USemaphore &S_Create() { static USemaphore S; return S; }
00212
00213 static THREAD_RET_T THREAD_CALL ThreadMainHandler( Instance *Param )
00214 {
00215 Instance I(*Param);
00216 Thread_T Data(I.Data);
00217 S_Create().Post();
00218
00219 if ( I.Owner )
00220 I.Owner->ThreadMain(Data);
00221 else
00222 I.pFN(Data);
00223
00224 Exit();
00225 THREAD_RETURN(0);
00226 }
00227
00228 struct Instance
00229 {
00230 Instance( Thread_C_R P, UThreadC<Thread_T> *const &O, const typename UThreadC<Thread_T>::Handler &pH = 0 )
00231 : pFN(pH), Data(P), Owner(O) {}
00232
00233 typename UThreadC<Thread_T>::Handler pFN;
00234 typename UThreadC<Thread_T>::Thread_C_R Data;
00235 UThreadC<Thread_T> * Owner;
00236
00237 };
00238 };
00239
00241
00242
00243 template<>
00244 class UTILITE_EXP UThreadC<void>
00245 {
00246 private:
00247 struct Instance;
00248
00249 public:
00250 typedef THREAD_HANDLE Handle;
00251 typedef void ( *Handler)();
00252
00253 virtual ~UThreadC<void>() {}
00254
00255 protected:
00256 UThreadC<void>() {}
00257
00258 virtual void ThreadMain() = 0;
00259
00260 static void Exit()
00261 { EXIT_THREAD; }
00262
00263 static void TestCancel()
00264 { Sleep(0); }
00265
00266 static int Self()
00267 {
00268 return (int)GetCurrentThreadId();
00269
00270
00271
00272
00273
00274
00275 }
00276
00277 public:
00278
00279 static int Create(
00280 const Handler & Function,
00281 Handle * const & H = 0,
00282 const bool & CreateDetached = false,
00283 const unsigned int & StackSize = 0,
00284 const bool & CancelEnable = false,
00285 const bool & CancelAsync = false
00286 )
00287 {
00288 Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler_S,Function));
00289
00290 if ( Hnd == CREATE_THREAD_FAILED )
00291 {
00292 if ( H ) *H = InvalidHandle;
00293 return (int)CREATE_THREAD_ERROR;
00294 }
00295
00296 if ( H ) *H = Hnd;
00297 if ( CreateDetached ) CLOSE_HANDLE(Hnd);
00298 return 0;
00299 }
00300
00301 int Create(
00302 Handle * const & H = 0,
00303 const bool & CreateDetached = false,
00304 const unsigned int & StackSize = 0,
00305 const bool & CancelEnable = false,
00306 const bool & CancelAsync = false
00307 ) const
00308 {
00309 Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,this));
00310
00311 if ( Hnd == CREATE_THREAD_FAILED )
00312 {
00313 if ( H ) *H = InvalidHandle;
00314 return (int)CREATE_THREAD_ERROR;
00315 }
00316
00317 if ( H ) *H = Hnd;
00318 if ( CreateDetached ) CLOSE_HANDLE(Hnd);
00319 Self();
00320 return 0;
00321 }
00322
00323 int Create(
00324 unsigned long & ThreadId,
00325 Handle * const & H = 0,
00326 const bool & CreateDetached = false,
00327 const unsigned int & StackSize = 0,
00328 const bool & CancelEnable = false,
00329 const bool & CancelAsync = false
00330 ) const
00331 {
00332 *H = InvalidHandle;
00333 int id;
00334 *H = CREATE_THREAD2(StackSize,ThreadMainHandler,this, (LPDWORD)&id);
00335 ThreadId = (unsigned long)id;
00336
00337 if ( *H == CREATE_THREAD_FAILED )
00338 {
00339 *H = InvalidHandle;
00340 return (int)CREATE_THREAD_ERROR;
00341 }
00342
00343 if ( CreateDetached ) CLOSE_HANDLE(*H);
00344 return 0;
00345 }
00346
00347 static int Join( const Handle &H )
00348 {
00349 DWORD R = WaitForSingleObject((HANDLE)H,INFINITE);
00350
00351 if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) )
00352 {
00353 CLOSE_HANDLE(H);
00354 return 0;
00355 }
00356
00357 if ( R == WAIT_TIMEOUT ) return EAGAIN;
00358 return EINVAL;
00359 }
00360
00361 static int Kill( const Handle &H )
00362 { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; }
00363
00364 static int Detach( const Handle &H )
00365 { return (CLOSE_HANDLE(H)?0:EINVAL); }
00366
00367 private:
00368
00369 static THREAD_RET_T THREAD_CALL ThreadMainHandler( UThreadC<void> *Param )
00370 {
00371 Param->ThreadMain();
00372 Exit();
00373 THREAD_RETURN(0);
00374 }
00375
00376 static THREAD_RET_T THREAD_CALL ThreadMainHandler_S( Handler Param )
00377 {
00378 Param();
00379 Exit();
00380 THREAD_RETURN(0);
00381 }
00382 };
00383
00384 #endif // !_U_Thread_Win32_