UThreadC.h
Go to the documentation of this file.
00001 
00002 //  Written by Phillip Sitbon
00003 //  Copyright 2003
00004 //
00005 //  Modified by Mathieu Labbe
00006 //
00007 //  Posix/Thread.h
00008 //    - Posix thread
00009 //
00011 
00012 #ifndef _U_Thread_Posix_
00013 #define _U_Thread_Posix_
00014 
00015 #include "rtabmap/utilite/USemaphore.h"
00016 #include "rtabmap/utilite/UMutex.h"
00017 
00018 #include <pthread.h>
00019 
00023 inline void uSleep(unsigned int ms)
00024 {
00025         struct timespec req;
00026         struct timespec rem;
00027         req.tv_sec = ms / 1000;
00028         req.tv_nsec = (ms - req.tv_sec * 1000) * 1000 * 1000;
00029         nanosleep (&req, &rem);
00030 }
00031 
00035 inline void uSleepMicro(unsigned int us)
00036 {
00037         struct timespec req;
00038         struct timespec rem;
00039         req.tv_sec = us / 1000000;
00040         req.tv_nsec = (us - req.tv_sec * 1000000) * 1000;
00041         nanosleep (&req, &rem);
00042 }
00043 
00047 inline void uSleepNano(unsigned int ns)
00048 {
00049         struct timespec req;
00050         struct timespec rem;
00051         req.tv_sec = ns / 1000000000;
00052         req.tv_nsec = (ns - req.tv_sec * 1000000000);
00053         nanosleep (&req, &rem);
00054 }
00055 
00056 
00057 #define InvalidHandle 0
00058 #define THREAD_HANDLE pthread_t
00059 
00060 typedef void *( * pthread_fn )( void * );
00061 
00062 template
00063 <
00064   typename Thread_T
00065 >
00066 class UThreadC
00067 {
00068   private:
00069     struct Instance;
00070 
00071   public:
00072     typedef Thread_T              & Thread_R;
00073     typedef const Thread_T        & Thread_C_R;
00074 
00075     typedef THREAD_HANDLE Handle;
00076     typedef void ( *Handler)( Thread_R );
00077 
00078     virtual ~UThreadC() {}
00079 
00080   protected:
00081     UThreadC() {}
00082 
00083     virtual void ThreadMain( Thread_R ) = 0;
00084 
00085     static void Exit()
00086       { pthread_exit(0); }
00087 #ifndef ANDROID
00088     static void TestCancel()
00089       { pthread_testcancel(); }
00090 #endif
00091 
00092     static Handle Self()
00093       { return (Handle)pthread_self(); }
00094 
00095   public:
00096 
00097     static int Create(
00098       const Handler       & Function,
00099       Thread_C_R            Param,
00100       Handle  * const     & H               = 0,
00101       const bool          & CreateDetached  = false,
00102       const unsigned int  & StackSize       = 0,
00103       const bool          & CancelEnable    = false,
00104       const bool          & CancelAsync     = false
00105     )
00106     {
00107       M_Create().lock();
00108       pthread_attr_t attr;
00109       pthread_attr_init(&attr);
00110 
00111       if ( CreateDetached )
00112         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00113 
00114       if ( StackSize )
00115         pthread_attr_setstacksize(&attr,StackSize);
00116 
00117       Instance I(Param,0,Function,CancelEnable,CancelAsync);
00118 
00119       Handle h=InvalidHandle;
00120       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00121 
00122       pthread_attr_destroy(&attr);
00123 
00124       if(H) *H = h;
00125       if ( !R ) S_Create().acquire();
00126 
00127           M_Create().unlock();
00128           return R;
00129     }
00130 
00131     int Create(
00132       Thread_C_R            Param,
00133       Handle  * const     & H               = 0,
00134       const bool          & CreateDetached  = false,
00135       const unsigned int  & StackSize       = 0,
00136       const bool          & CancelEnable    = false,
00137       const bool          & CancelAsync     = false
00138     ) const
00139     {
00140       M_Create().lock();
00141       pthread_attr_t attr;
00142       pthread_attr_init(&attr);
00143 
00144       if ( CreateDetached )
00145         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00146 
00147       if ( StackSize )
00148         pthread_attr_setstacksize(&attr,StackSize);
00149 
00150       Instance I(Param,const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00151 
00152       Handle h=InvalidHandle;
00153       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00154 
00155       pthread_attr_destroy(&attr);
00156 
00157       if(H) *H = h;
00158       if ( !R ) S_Create().acquire();
00159 
00160           M_Create().unlock();
00161           return R;
00162     }
00163 
00164     static int Join( Handle H )
00165       { return pthread_join(H,0); }
00166 
00167 #ifndef ANDROID
00168     static int Kill( Handle H )
00169       { return pthread_cancel(H); }
00170 #endif
00171 
00172     static int Detach( Handle H )
00173       { return pthread_detach(H); }
00174 
00175   private:
00176 
00177     static const UMutex &M_Create()      { static UMutex M; return M; }
00178     static USemaphore &S_Create()  { static USemaphore S; return S; }
00179 
00180     static void *ThreadMainHandler( Instance *Param )
00181     {
00182       Instance  I(*Param);
00183       Thread_T  Data(I.Data);
00184       S_Create().release();
00185 
00186 #ifndef ANDROID
00187       if ( I.Flags & 1 /*CancelEnable*/ )
00188       {
00189         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
00190 
00191         if ( I.Flags & 2 /*CancelAsync*/ )
00192           pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
00193         else
00194           pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
00195       }
00196       else
00197       {
00198         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
00199       }
00200 #endif
00201 
00202       if ( I.Owner )
00203         I.Owner->ThreadMain(Data);
00204       else
00205         I.pFN(Data);
00206 
00207       return 0;
00208     }
00209 
00210     struct Instance
00211     {
00212       Instance( Thread_C_R P, UThreadC<Thread_T> *const &O, const UThreadC<Thread_T>::Handler &pH = 0, const bool &CE=false, const bool &CA=false )
00213         : Data(P), Owner(O), pFN(pH), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
00214 
00215       Thread_C_R      Data;
00216       UThreadC<Thread_T>                * Owner;
00217       Handler         pFN;
00218       unsigned char                     Flags;
00219     };
00220 };
00221 
00223 //  Explicit specialization, no thread parameters
00224 //
00225 template<>
00226 class UThreadC<void>
00227 {
00228   private:
00229     struct Instance;
00230 
00231   public:
00232     typedef THREAD_HANDLE Handle;
00233     typedef void ( *Handler)();
00234 
00235     virtual ~UThreadC<void>() {}
00236 
00237   protected:
00238     UThreadC<void>() {}
00239 
00240     virtual void ThreadMain() = 0;
00241 
00242     static void Exit()
00243       { pthread_exit(0); }
00244 
00245 #ifndef ANDROID
00246     static void TestCancel()
00247       { pthread_testcancel(); }
00248 #endif
00249 
00250     static Handle Self()
00251       { return (Handle)pthread_self(); }
00252 
00253   public:
00254 
00255     static int Create(
00256       const Handler       & Function,
00257       Handle  * const     & H               = 0,
00258       const bool          & CreateDetached  = false,
00259       const unsigned int  & StackSize       = 0,
00260       const bool          & CancelEnable    = false,
00261       const bool          & CancelAsync     = false
00262     )
00263     {
00264       M_Create().lock();
00265       pthread_attr_t attr;
00266       pthread_attr_init(&attr);
00267 
00268       if ( CreateDetached )
00269         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00270 
00271       if ( StackSize )
00272         pthread_attr_setstacksize(&attr,StackSize);
00273 
00274       Instance I(0,Function,CancelEnable,CancelAsync);
00275 
00276       Handle h=InvalidHandle;
00277       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00278 
00279       pthread_attr_destroy(&attr);
00280 
00281       if(H) *H = h;
00282       if ( !R ) S_Create().acquire();
00283 
00284           M_Create().unlock();
00285           return R;
00286     }
00287 
00288     int Create(
00289       Handle  * const     & H               = 0,
00290       const bool          & CreateDetached  = false,
00291       const unsigned int  & StackSize       = 0,
00292       const bool          & CancelEnable    = false,
00293       const bool          & CancelAsync     = false
00294     ) const
00295     {
00296       M_Create().lock();
00297       pthread_attr_t attr;
00298       pthread_attr_init(&attr);
00299 
00300       if ( CreateDetached )
00301         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00302 
00303       if ( StackSize )
00304         pthread_attr_setstacksize(&attr,StackSize);
00305 
00306       Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00307 
00308       Handle h=InvalidHandle;
00309       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00310 
00311       pthread_attr_destroy(&attr);
00312 
00313       if(H) *H = h;
00314       if ( !R ) S_Create().acquire();
00315 
00316           M_Create().unlock();
00317           return R;
00318     }
00319 
00320     int Create(
00321       unsigned long        & ThreadId,
00322       Handle  * const     & H               = 0,
00323       const bool          & CreateDetached  = false,
00324       const unsigned int  & StackSize       = 0,
00325       const bool          & CancelEnable    = false,
00326       const bool          & CancelAsync     = false
00327     ) const
00328     {
00329       M_Create().lock();
00330       pthread_attr_t attr;
00331       pthread_attr_init(&attr);
00332 
00333       if ( CreateDetached )
00334         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00335 
00336       if ( StackSize )
00337         pthread_attr_setstacksize(&attr,StackSize);
00338 
00339       Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00340 
00341       *H = InvalidHandle;
00342       int R = pthread_create((pthread_t *)&(*H),&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00343 
00344       ThreadId = (unsigned long)*H;
00345 
00346       pthread_attr_destroy(&attr);
00347 
00348       if ( !R ) S_Create().acquire();
00349 
00350       M_Create().unlock();
00351       return R;
00352     }
00353 
00354     static int Join( Handle H )
00355       { return pthread_join(H,0); }
00356 
00357 #ifndef ANDROID
00358     static int Kill( Handle H )
00359       { return pthread_cancel(H); }
00360 #endif
00361 
00362     static int Detach( Handle H )
00363       { return pthread_detach(H); }
00364 
00365   private:
00366 
00367     static const UMutex &M_Create()      { static UMutex M; return M; }
00368     static USemaphore &S_Create()  { static USemaphore S; return S; }
00369 
00370     static void *ThreadMainHandler( Instance *Param )
00371     {
00372       Instance  I(*Param);
00373       S_Create().release();
00374 
00375 #ifndef ANDROID
00376       if ( I.Flags & 1 /*CancelEnable*/ )
00377       {
00378         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
00379 
00380         if ( I.Flags & 2 /*CancelAsync*/ )
00381           pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
00382         else
00383           pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
00384       }
00385       else
00386       {
00387         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
00388       }
00389 #endif
00390 
00391       if ( I.Owner )
00392         I.Owner->ThreadMain();
00393       else
00394         I.pFN();
00395 
00396       return 0;
00397     }
00398 
00399     struct Instance
00400     {
00401                 Instance( UThreadC<void> *const &O, const UThreadC<void>::Handler &pH = 0, const bool &CE=false, const bool &CA=false )
00402         : pFN(pH), Owner(O), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
00403 
00404                 UThreadC<void>::Handler             pFN;
00405                 UThreadC<void>                *     Owner;
00406                 unsigned char                     Flags;
00407 
00408     };
00409 };
00410 
00411 #endif // !_U_Thread_Posix_


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:32