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 
00088     static void TestCancel()
00089       { pthread_testcancel(); }
00090 
00091     static Handle Self()
00092       { return (Handle)pthread_self(); }
00093 
00094   public:
00095 
00096     static int Create(
00097       const Handler       & Function,
00098       Thread_C_R            Param,
00099       Handle  * const     & H               = 0,
00100       const bool          & CreateDetached  = false,
00101       const unsigned int  & StackSize       = 0,
00102       const bool          & CancelEnable    = false,
00103       const bool          & CancelAsync     = false
00104     )
00105     {
00106       M_Create().lock();
00107       pthread_attr_t attr;
00108       pthread_attr_init(&attr);
00109 
00110       if ( CreateDetached )
00111         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00112 
00113       if ( StackSize )
00114         pthread_attr_setstacksize(&attr,StackSize);
00115 
00116       Instance I(Param,0,Function,CancelEnable,CancelAsync);
00117 
00118       Handle h=InvalidHandle;
00119       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00120 
00121       pthread_attr_destroy(&attr);
00122 
00123       if(H) *H = h;
00124       if ( !R ) S_Create().acquire();
00125 
00126           M_Create().unlock();
00127           return R;
00128     }
00129 
00130     int Create(
00131       Thread_C_R            Param,
00132       Handle  * const     & H               = 0,
00133       const bool          & CreateDetached  = false,
00134       const unsigned int  & StackSize       = 0,
00135       const bool          & CancelEnable    = false,
00136       const bool          & CancelAsync     = false
00137     ) const
00138     {
00139       M_Create().lock();
00140       pthread_attr_t attr;
00141       pthread_attr_init(&attr);
00142 
00143       if ( CreateDetached )
00144         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00145 
00146       if ( StackSize )
00147         pthread_attr_setstacksize(&attr,StackSize);
00148 
00149       Instance I(Param,const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00150 
00151       Handle h=InvalidHandle;
00152       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00153 
00154       pthread_attr_destroy(&attr);
00155 
00156       if(H) *H = h;
00157       if ( !R ) S_Create().acquire();
00158 
00159           M_Create().unlock();
00160           return R;
00161     }
00162 
00163     static int Join( Handle H )
00164       { return pthread_join(H,0); }
00165 
00166     static int Kill( Handle H )
00167       { return pthread_cancel(H); }
00168 
00169     static int Detach( Handle H )
00170       { return pthread_detach(H); }
00171 
00172   private:
00173 
00174     static const UMutex &M_Create()      { static UMutex M; return M; }
00175     static USemaphore &S_Create()  { static USemaphore S; return S; }
00176 
00177     static void *ThreadMainHandler( Instance *Param )
00178     {
00179       Instance  I(*Param);
00180       Thread_T  Data(I.Data);
00181       S_Create().release();
00182 
00183       if ( I.Flags & 1 /*CancelEnable*/ )
00184       {
00185         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
00186 
00187         if ( I.Flags & 2 /*CancelAsync*/ )
00188           pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
00189         else
00190           pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
00191       }
00192       else
00193       {
00194         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
00195       }
00196 
00197       if ( I.Owner )
00198         I.Owner->ThreadMain(Data);
00199       else
00200         I.pFN(Data);
00201 
00202       return 0;
00203     }
00204 
00205     struct Instance
00206     {
00207       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 )
00208         : Data(P), Owner(O), pFN(pH), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
00209 
00210       Thread_C_R      Data;
00211       UThreadC<Thread_T>                * Owner;
00212       Handler         pFN;
00213       unsigned char                     Flags;
00214     };
00215 };
00216 
00218 //  Explicit specialization, no thread parameters
00219 //
00220 template<>
00221 class UThreadC<void>
00222 {
00223   private:
00224     struct Instance;
00225 
00226   public:
00227     typedef THREAD_HANDLE Handle;
00228     typedef void ( *Handler)();
00229 
00230     virtual ~UThreadC<void>() {}
00231 
00232   protected:
00233     UThreadC<void>() {}
00234 
00235     virtual void ThreadMain() = 0;
00236 
00237     static void Exit()
00238       { pthread_exit(0); }
00239 
00240     static void TestCancel()
00241       { pthread_testcancel(); }
00242 
00243     static Handle Self()
00244       { return (Handle)pthread_self(); }
00245 
00246   public:
00247 
00248     static int Create(
00249       const Handler       & Function,
00250       Handle  * const     & H               = 0,
00251       const bool          & CreateDetached  = false,
00252       const unsigned int  & StackSize       = 0,
00253       const bool          & CancelEnable    = false,
00254       const bool          & CancelAsync     = false
00255     )
00256     {
00257       M_Create().lock();
00258       pthread_attr_t attr;
00259       pthread_attr_init(&attr);
00260 
00261       if ( CreateDetached )
00262         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00263 
00264       if ( StackSize )
00265         pthread_attr_setstacksize(&attr,StackSize);
00266 
00267       Instance I(0,Function,CancelEnable,CancelAsync);
00268 
00269       Handle h=InvalidHandle;
00270       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00271 
00272       pthread_attr_destroy(&attr);
00273 
00274       if(H) *H = h;
00275       if ( !R ) S_Create().acquire();
00276 
00277           M_Create().unlock();
00278           return R;
00279     }
00280 
00281     int Create(
00282       Handle  * const     & H               = 0,
00283       const bool          & CreateDetached  = false,
00284       const unsigned int  & StackSize       = 0,
00285       const bool          & CancelEnable    = false,
00286       const bool          & CancelAsync     = false
00287     ) const
00288     {
00289       M_Create().lock();
00290       pthread_attr_t attr;
00291       pthread_attr_init(&attr);
00292 
00293       if ( CreateDetached )
00294         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00295 
00296       if ( StackSize )
00297         pthread_attr_setstacksize(&attr,StackSize);
00298 
00299       Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00300 
00301       Handle h=InvalidHandle;
00302       int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00303 
00304       pthread_attr_destroy(&attr);
00305 
00306       if(H) *H = h;
00307       if ( !R ) S_Create().acquire();
00308 
00309           M_Create().unlock();
00310           return R;
00311     }
00312 
00313     int Create(
00314       unsigned long        & ThreadId,
00315       Handle  * const     & H               = 0,
00316       const bool          & CreateDetached  = false,
00317       const unsigned int  & StackSize       = 0,
00318       const bool          & CancelEnable    = false,
00319       const bool          & CancelAsync     = false
00320     ) const
00321     {
00322       M_Create().lock();
00323       pthread_attr_t attr;
00324       pthread_attr_init(&attr);
00325 
00326       if ( CreateDetached )
00327         pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
00328 
00329       if ( StackSize )
00330         pthread_attr_setstacksize(&attr,StackSize);
00331 
00332       Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
00333 
00334       *H = InvalidHandle;
00335       int R = pthread_create((pthread_t *)&(*H),&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
00336 
00337       ThreadId = (unsigned long)*H;
00338 
00339       pthread_attr_destroy(&attr);
00340 
00341       if ( !R ) S_Create().acquire();
00342 
00343       M_Create().unlock();
00344       return R;
00345     }
00346 
00347     static int Join( Handle H )
00348       { return pthread_join(H,0); }
00349 
00350     static int Kill( Handle H )
00351       { return pthread_cancel(H); }
00352 
00353     static int Detach( Handle H )
00354       { return pthread_detach(H); }
00355 
00356   private:
00357 
00358     static const UMutex &M_Create()      { static UMutex M; return M; }
00359     static USemaphore &S_Create()  { static USemaphore S; return S; }
00360 
00361     static void *ThreadMainHandler( Instance *Param )
00362     {
00363       Instance  I(*Param);
00364       S_Create().release();
00365 
00366       if ( I.Flags & 1 /*CancelEnable*/ )
00367       {
00368         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
00369 
00370         if ( I.Flags & 2 /*CancelAsync*/ )
00371           pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
00372         else
00373           pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
00374       }
00375       else
00376       {
00377         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
00378       }
00379 
00380       if ( I.Owner )
00381         I.Owner->ThreadMain();
00382       else
00383         I.pFN();
00384 
00385       return 0;
00386     }
00387 
00388     struct Instance
00389     {
00390                 Instance( UThreadC<void> *const &O, const UThreadC<void>::Handler &pH = 0, const bool &CE=false, const bool &CA=false )
00391         : pFN(pH), Owner(O), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
00392 
00393                 UThreadC<void>::Handler             pFN;
00394                 UThreadC<void>                *     Owner;
00395                 unsigned char                     Flags;
00396 
00397     };
00398 };
00399 
00400 #endif // !_U_Thread_Posix_


rtabmap
Author(s): Mathieu Labbe
autogenerated on Fri Aug 28 2015 12:51:42