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 int & 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 *H = CREATE_THREAD2(StackSize,ThreadMainHandler,this, (LPDWORD)&ThreadId);
00334
00335 if ( *H == CREATE_THREAD_FAILED )
00336 {
00337 *H = InvalidHandle;
00338 return (int)CREATE_THREAD_ERROR;
00339 }
00340
00341 if ( CreateDetached ) CLOSE_HANDLE(*H);
00342 return 0;
00343 }
00344
00345 static int Join( const Handle &H )
00346 {
00347 DWORD R = WaitForSingleObject((HANDLE)H,INFINITE);
00348
00349 if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) )
00350 {
00351 CLOSE_HANDLE(H);
00352 return 0;
00353 }
00354
00355 if ( R == WAIT_TIMEOUT ) return EAGAIN;
00356 return EINVAL;
00357 }
00358
00359 static int Kill( const Handle &H )
00360 { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; }
00361
00362 static int Detach( const Handle &H )
00363 { return (CLOSE_HANDLE(H)?0:EINVAL); }
00364
00365 private:
00366
00367 static THREAD_RET_T THREAD_CALL ThreadMainHandler( UThreadC<void> *Param )
00368 {
00369 Param->ThreadMain();
00370 Exit();
00371 THREAD_RETURN(0);
00372 }
00373
00374 static THREAD_RET_T THREAD_CALL ThreadMainHandler_S( Handler Param )
00375 {
00376 Param();
00377 Exit();
00378 THREAD_RETURN(0);
00379 }
00380 };
00381
00382 #endif // !_U_Thread_Win32_