RTAB-Map 0.23.10
Real-Time Appearance-Based Mapping
Loading...
Searching...
No Matches
UThreadC.h
1
2// 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
15#include "rtabmap/utilite/USemaphore.h"
16#include "rtabmap/utilite/UMutex.h"
17
18#include <pthread.h>
19
23inline 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
35inline 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
47inline 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
60typedef void *( * pthread_fn )( void * );
61
62template
63<
64 typename Thread_T
65>
67{
68 private:
69 struct Instance;
70
71 public:
72 typedef Thread_T & Thread_R;
73 typedef const Thread_T & Thread_C_R;
74
75 typedef THREAD_HANDLE Handle;
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;
216 UThreadC<Thread_T> * Owner;
217 Handler pFN;
218 unsigned char Flags;
219 };
220};
221
223// Explicit specialization, no thread parameters
224//
225template<>
226class UThreadC<void>
227{
228 private:
229 struct Instance;
230
231 public:
232 typedef THREAD_HANDLE Handle;
233 typedef void ( *Handler)();
234
235 virtual ~UThreadC() {}
236
237 protected:
238 UThreadC() {}
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
405 UThreadC<void> * Owner;
406 unsigned char Flags;
407
408 };
409};
410
411#endif // !_U_Thread_Posix_
int unlock() const
Definition UMutex.h:120
int lock() const
Definition UMutex.h:88
bool acquire(int n=1, int ms=0)
Definition USemaphore.h:108
int release(int n=1)
Definition USemaphore.h:197