Posix/UThreadC.h
Go to the documentation of this file.
1 // Written by Phillip Sitbon
3 // Copyright 2003
4 //
5 // Modified by Mathieu Labbe
6 //
7 // Posix/Thread.h
8 // - Posix thread
9 //
11 
12 #ifndef _U_Thread_Posix_
13 #define _U_Thread_Posix_
14 
16 #include "rtabmap/utilite/UMutex.h"
17 
18 #include <pthread.h>
19 
23 inline void uSleep(unsigned int ms)
24 {
25  struct timespec req;
26  struct timespec rem;
27  req.tv_sec = ms / 1000;
28  req.tv_nsec = (ms - req.tv_sec * 1000) * 1000 * 1000;
29  nanosleep (&req, &rem);
30 }
31 
35 inline void uSleepMicro(unsigned int us)
36 {
37  struct timespec req;
38  struct timespec rem;
39  req.tv_sec = us / 1000000;
40  req.tv_nsec = (us - req.tv_sec * 1000000) * 1000;
41  nanosleep (&req, &rem);
42 }
43 
47 inline void uSleepNano(unsigned int ns)
48 {
49  struct timespec req;
50  struct timespec rem;
51  req.tv_sec = ns / 1000000000;
52  req.tv_nsec = (ns - req.tv_sec * 1000000000);
53  nanosleep (&req, &rem);
54 }
55 
56 
57 #define InvalidHandle 0
58 #define THREAD_HANDLE pthread_t
59 
60 typedef void *( * pthread_fn )( void * );
61 
62 template
63 <
64  typename Thread_T
65 >
66 class UThreadC
67 {
68  private:
69  struct Instance;
70 
71  public:
72  typedef Thread_T & Thread_R;
73  typedef const Thread_T & Thread_C_R;
74 
76  typedef void ( *Handler)( Thread_R );
77 
78  virtual ~UThreadC() {}
79 
80  protected:
81  UThreadC() {}
82 
83  virtual void ThreadMain( Thread_R ) = 0;
84 
85  static void Exit()
86  { pthread_exit(0); }
87 #ifndef ANDROID
88  static void TestCancel()
89  { pthread_testcancel(); }
90 #endif
91 
92  static Handle Self()
93  { return (Handle)pthread_self(); }
94 
95  public:
96 
97  static int Create(
98  const Handler & Function,
99  Thread_C_R Param,
100  Handle * const & H = 0,
101  const bool & CreateDetached = false,
102  const unsigned int & StackSize = 0,
103  const bool & CancelEnable = false,
104  const bool & CancelAsync = false
105  )
106  {
107  M_Create().lock();
108  pthread_attr_t attr;
109  pthread_attr_init(&attr);
110 
111  if ( CreateDetached )
112  pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
113 
114  if ( StackSize )
115  pthread_attr_setstacksize(&attr,StackSize);
116 
117  Instance I(Param,0,Function,CancelEnable,CancelAsync);
118 
119  Handle h=InvalidHandle;
120  int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
121 
122  pthread_attr_destroy(&attr);
123 
124  if(H) *H = h;
125  if ( !R ) S_Create().acquire();
126 
127  M_Create().unlock();
128  return R;
129  }
130 
131  int Create(
132  Thread_C_R Param,
133  Handle * const & H = 0,
134  const bool & CreateDetached = false,
135  const unsigned int & StackSize = 0,
136  const bool & CancelEnable = false,
137  const bool & CancelAsync = false
138  ) const
139  {
140  M_Create().lock();
141  pthread_attr_t attr;
142  pthread_attr_init(&attr);
143 
144  if ( CreateDetached )
145  pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
146 
147  if ( StackSize )
148  pthread_attr_setstacksize(&attr,StackSize);
149 
150  Instance I(Param,const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
151 
152  Handle h=InvalidHandle;
153  int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
154 
155  pthread_attr_destroy(&attr);
156 
157  if(H) *H = h;
158  if ( !R ) S_Create().acquire();
159 
160  M_Create().unlock();
161  return R;
162  }
163 
164  static int Join( Handle H )
165  { return pthread_join(H,0); }
166 
167 #ifndef ANDROID
168  static int Kill( Handle H )
169  { return pthread_cancel(H); }
170 #endif
171 
172  static int Detach( Handle H )
173  { return pthread_detach(H); }
174 
175  private:
176 
177  static const UMutex &M_Create() { static UMutex M; return M; }
178  static USemaphore &S_Create() { static USemaphore S; return S; }
179 
180  static void *ThreadMainHandler( Instance *Param )
181  {
182  Instance I(*Param);
183  Thread_T Data(I.Data);
184  S_Create().release();
185 
186 #ifndef ANDROID
187  if ( I.Flags & 1 /*CancelEnable*/ )
188  {
189  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
190 
191  if ( I.Flags & 2 /*CancelAsync*/ )
192  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
193  else
194  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
195  }
196  else
197  {
198  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
199  }
200 #endif
201 
202  if ( I.Owner )
203  I.Owner->ThreadMain(Data);
204  else
205  I.pFN(Data);
206 
207  return 0;
208  }
209 
210  struct Instance
211  {
212  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 )
213  : Data(P), Owner(O), pFN(pH), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
214 
215  Thread_C_R Data;
218  unsigned char Flags;
219  };
220 };
221 
223 // Explicit specialization, no thread parameters
224 //
225 template<>
226 class UThreadC<void>
227 {
228  private:
229  struct Instance;
230 
231  public:
232  typedef THREAD_HANDLE Handle;
233  typedef void ( *Handler)();
234 
235  virtual ~UThreadC<void>() {}
236 
237  protected:
239 
240  virtual void ThreadMain() = 0;
241 
242  static void Exit()
243  { pthread_exit(0); }
244 
245 #ifndef ANDROID
246  static void TestCancel()
247  { pthread_testcancel(); }
248 #endif
249 
250  static Handle Self()
251  { return (Handle)pthread_self(); }
252 
253  public:
254 
255  static int Create(
256  const Handler & Function,
257  Handle * const & H = 0,
258  const bool & CreateDetached = false,
259  const unsigned int & StackSize = 0,
260  const bool & CancelEnable = false,
261  const bool & CancelAsync = false
262  )
263  {
264  M_Create().lock();
265  pthread_attr_t attr;
266  pthread_attr_init(&attr);
267 
268  if ( CreateDetached )
269  pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
270 
271  if ( StackSize )
272  pthread_attr_setstacksize(&attr,StackSize);
273 
274  Instance I(0,Function,CancelEnable,CancelAsync);
275 
276  Handle h=InvalidHandle;
277  int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
278 
279  pthread_attr_destroy(&attr);
280 
281  if(H) *H = h;
282  if ( !R ) S_Create().acquire();
283 
284  M_Create().unlock();
285  return R;
286  }
287 
288  int Create(
289  Handle * const & H = 0,
290  const bool & CreateDetached = false,
291  const unsigned int & StackSize = 0,
292  const bool & CancelEnable = false,
293  const bool & CancelAsync = false
294  ) const
295  {
296  M_Create().lock();
297  pthread_attr_t attr;
298  pthread_attr_init(&attr);
299 
300  if ( CreateDetached )
301  pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
302 
303  if ( StackSize )
304  pthread_attr_setstacksize(&attr,StackSize);
305 
306  Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
307 
308  Handle h=InvalidHandle;
309  int R = pthread_create((pthread_t *)&h,&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
310 
311  pthread_attr_destroy(&attr);
312 
313  if(H) *H = h;
314  if ( !R ) S_Create().acquire();
315 
316  M_Create().unlock();
317  return R;
318  }
319 
320  int Create(
321  unsigned long & ThreadId,
322  Handle * const & H = 0,
323  const bool & CreateDetached = false,
324  const unsigned int & StackSize = 0,
325  const bool & CancelEnable = false,
326  const bool & CancelAsync = false
327  ) const
328  {
329  M_Create().lock();
330  pthread_attr_t attr;
331  pthread_attr_init(&attr);
332 
333  if ( CreateDetached )
334  pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
335 
336  if ( StackSize )
337  pthread_attr_setstacksize(&attr,StackSize);
338 
339  Instance I(const_cast<UThreadC *>(this),0,CancelEnable,CancelAsync);
340 
341  *H = InvalidHandle;
342  int R = pthread_create((pthread_t *)&(*H),&attr,(pthread_fn)ThreadMainHandler,(void *)&I);
343 
344  ThreadId = (unsigned long)*H;
345 
346  pthread_attr_destroy(&attr);
347 
348  if ( !R ) S_Create().acquire();
349 
350  M_Create().unlock();
351  return R;
352  }
353 
354  static int Join( Handle H )
355  { return pthread_join(H,0); }
356 
357 #ifndef ANDROID
358  static int Kill( Handle H )
359  { return pthread_cancel(H); }
360 #endif
361 
362  static int Detach( Handle H )
363  { return pthread_detach(H); }
364 
365  private:
366 
367  static const UMutex &M_Create() { static UMutex M; return M; }
368  static USemaphore &S_Create() { static USemaphore S; return S; }
369 
370  static void *ThreadMainHandler( Instance *Param )
371  {
372  Instance I(*Param);
373  S_Create().release();
374 
375 #ifndef ANDROID
376  if ( I.Flags & 1 /*CancelEnable*/ )
377  {
378  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
379 
380  if ( I.Flags & 2 /*CancelAsync*/ )
381  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
382  else
383  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
384  }
385  else
386  {
387  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
388  }
389 #endif
390 
391  if ( I.Owner )
392  I.Owner->ThreadMain();
393  else
394  I.pFN();
395 
396  return 0;
397  }
398 
399  struct Instance
400  {
401  Instance( UThreadC<void> *const &O, const UThreadC<void>::Handler &pH = 0, const bool &CE=false, const bool &CA=false )
402  : pFN(pH), Owner(O), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; }
403 
406  unsigned char Flags;
407 
408  };
409 };
410 
411 #endif // !_U_Thread_Posix_
Thread_T & Thread_R
#define NULL
void release(int n=1)
Definition: USemaphore.h:168
static int Detach(Handle H)
int Create(unsigned long &ThreadId, Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false) const
static int Kill(Handle H)
#define THREAD_HANDLE
static USemaphore & S_Create()
static void * ThreadMainHandler(Instance *Param)
static int Create(const Handler &Function, Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false)
static int Join(Handle H)
static int Create(const Handler &Function, Thread_C_R Param, Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false)
static USemaphore & S_Create()
THREAD_HANDLE Handle
bool acquire(int n=1, int ms=0)
Definition: USemaphore.h:101
Instance(UThreadC< void > *const &O, const UThreadC< void >::Handler &pH=0, const bool &CE=false, const bool &CA=false)
static int Join(Handle H)
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)
virtual void ThreadMain(Thread_R)=0
static Handle Self()
static int Detach(Handle H)
const Thread_T & Thread_C_R
static void * ThreadMainHandler(Instance *Param)
static int Kill(Handle H)
int lock() const
Definition: UMutex.h:87
void uSleepNano(unsigned int ns)
void *(* pthread_fn)(void *)
Definition: UMutex.h:54
UThreadC< void >::Handler pFN
static void TestCancel()
unsigned char Flags
int unlock() const
Definition: UMutex.h:113
UThreadC< Thread_T > * Owner
static const UMutex & M_Create()
virtual ~UThreadC()
void uSleep(unsigned int ms)
static const UMutex & M_Create()
void(* Handler)(Thread_R)
UThreadC< void > * Owner
void uSleepMicro(unsigned int us)
static void TestCancel()
static void Exit()
int Create(Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false) const
#define InvalidHandle
THREAD_HANDLE Handle
static void Exit()
int Create(Thread_C_R Param, Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false) const
static Handle Self()


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Jan 23 2023 03:38:58