Win32/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 // Win32/Thread.h
8 // - Windows thread
9 //
10 // - From CreateThread Platform SDK Documentation:
11 //
12 // "A thread that uses functions from the static C run-time
13 // libraries should use the beginthread and endthread C run-time
14 // functions for thread management rather than CreateThread and
15 // ExitThread. Failure to do so results in small memory leaks
16 // when ExitThread is called. Note that this is not a problem
17 // with the C run-time in a DLL."
18 //
19 // With regards to this, I have decided to use the CreateThread
20 // API, unless you define _CRT_ in which case there are two
21 // possibilities:
22 //
23 // 1. Define _USE_BEGINTHREAD: Uses _beginthread/_endthread
24 // (said to be *unreliable* in the SDK docs)
25 //
26 // 2. Don't - Uses _beginthreaded/_endthreadex
27 //
28 // A note about _endthread:
29 //
30 // It will call CloseHandle() on exit, and if it was already
31 // closed then you will get an exception. To prevent this, I
32 // removed the CloseHandle() functionality - this means that
33 // a Join() WILL wait on a Detach()'ed thread.
34 //
36 #ifndef _U_Thread_Win32_
37 #define _U_Thread_Win32_
38 
39 #include "rtabmap/utilite/utilite_export.h"
42 #include "rtabmap/utilite/UMutex.h"
43 
44 inline void uSleep(unsigned int ms)
45 {
46  Sleep(ms);
47 }
48 
49 #ifdef _CRT_
50 # include <process.h>
51 # ifdef _USE_BEGINTHREAD
52 # define THREAD_CALL __cdecl
53 # define THREAD_HANDLE uintptr_t
54 # define THREAD_RET_T void
55 # define CREATE_THREAD_FAILED (-1L)
56 # define CREATE_THREAD_ERROR (errno)
57 # define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthread((void (__cdecl *)(void *))_F,_S,(void *)_P))
58 # define EXIT_THREAD _endthread()
59 # define CLOSE_HANDLE(x) 1
60 # define THREAD_RETURN(x) return
61 # else
62 # define THREAD_CALL WINAPI
63 # define THREAD_HANDLE HANDLE
64 # define THREAD_RET_T UINT
65 # define CREATE_THREAD_FAILED (0L)
66 # define CREATE_THREAD_ERROR (errno)
67 # define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthreadex(0,_S,(UINT (WINAPI *)(void *))_F,(void *)_P,0,0))
68 # define EXIT_THREAD _endthreadex(0)
69 # define CLOSE_HANDLE(x) CloseHandle(x)
70 # define THREAD_RETURN(x) return(x)
71 # endif
72 #else
73 # define THREAD_CALL WINAPI
74 # define THREAD_HANDLE HANDLE
75 # define THREAD_RET_T DWORD
76 # define CREATE_THREAD_FAILED (0L)
77 # define CREATE_THREAD_ERROR GetLastError()
78 # define CREATE_THREAD(_S,_F,_P) ((Handle)CreateThread(0,_S,(DWORD (WINAPI *)(void *))_F,(void *)_P,0,0))
79 # define CREATE_THREAD2(_S,_F,_P,_ID) ((Handle)CreateThread(0,_S,(DWORD (WINAPI *)(void *))_F,(void *)_P,0,_ID))
80 # define EXIT_THREAD ExitThread(0)
81 # define CLOSE_HANDLE(x) CloseHandle(x)
82 # define THREAD_RETURN(x) return(x)
83 #endif
84 
85 #define InvalidHandle 0
86 
87 template
88 <
89  typename Thread_T
90 >
91 class UTILITE_EXPORT UThreadC
92 {
93  private:
94  struct Instance;
95 
96  public:
97  typedef Thread_T & Thread_R;
98  typedef const Thread_T & Thread_C_R;
99 
101  typedef void (* Handler)( Thread_R );
102 
103  protected:
104  UThreadC() {}
105 
106  virtual void ThreadMain( Thread_R ) = 0;
107 
108  static void Exit()
109  { EXIT_THREAD; }
110 
111  static void TestCancel()
112  { Sleep(0); }
113 
114  static int Self()
115  {
116  Handle Hnd = InvalidHandle;
117  DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),(LPHANDLE)&Hnd,NULL,0,NULL);
118  return Hnd;
119 
120  // only a pseudo-handle!
121  //return (Handle)GetCurrentThread();
122  }
123 
124  public:
125 
126  static int Create(
127  const Handler & Function,
128  Thread_C_R Param,
129  Handle * const & H = 0,
130  const bool & CreateDetached = false,
131  const unsigned int & StackSize = 0,
132  const bool & CancelEnable = false, // UNUSED
133  const bool & CancelAsync = false // UNUSED
134  )
135  {
136  M_Create().lock();
137 
138  Instance I(Param,0,Function);
139 
140  Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I));
141 
142  if ( Hnd == CREATE_THREAD_FAILED )
143  {
144  if ( H ) *H = InvalidHandle;
145  M_Create().unlock();
146  return CREATE_THREAD_ERROR;
147  }
148 
149  if ( H ) *H = Hnd;
150 
151  S_Create().Wait();
152  M_Create().unlock();
153 
154  if ( CreateDetached ) CLOSE_HANDLE(Hnd);
155  return 0;
156  }
157 
158  int Create(
159  Thread_C_R Param,
160  Handle * const & H = 0,
161  const bool & CreateDetached = false,
162  const unsigned int & StackSize = 0,
163  const bool & CancelEnable = false, // UNUSED
164  const bool & CancelAsync = false // UNUSED
165  ) const
166  {
167  M_Create().lock();
168 
169  Instance I(Param,const_cast<UThreadC *>(this));
170 
171  Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I));
172 
173  if ( Hnd == CREATE_THREAD_FAILED )
174  {
175  if ( H ) *H = InvalidHandle;
176  M_Create().unlock();
177  return CREATE_THREAD_ERROR;
178  }
179 
180  if ( H ) *H = Hnd;
181 
182  S_Create().Wait();
183  M_Create().unlock();
184 
185  if ( CreateDetached ) CLOSE_HANDLE(Hnd);
186  return 0;
187  }
188 
189  static int Join( const Handle &H )
190  {
191  DWORD R = WaitForSingleObject((HANDLE)H,INFINITE);
192 
193  if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) )
194  {
195  CLOSE_HANDLE(H);
196  return 0;
197  }
198 
199  if ( R == WAIT_TIMEOUT ) return EAGAIN;
200  return EINVAL;
201  }
202 
203  static int Kill( const Handle &H )
204  { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; }
205 
206  static int Detach( const Handle &H )
207  { return (CLOSE_HANDLE(H)?0:EINVAL); }
208 
209  private:
210 
211  static const UMutex &M_Create() { static UMutex M; return M; }
212  static const USemaphore &S_Create() { static USemaphore S; return S; }
213 
215  {
216  Instance I(*Param);
217  Thread_T Data(I.Data);
218  S_Create().Post();
219 
220  if ( I.Owner )
221  I.Owner->ThreadMain(Data);
222  else
223  I.pFN(Data);
224 
225  Exit();
226  THREAD_RETURN(0);
227  }
228 
229  struct Instance
230  {
231  Instance( Thread_C_R P, UThreadC<Thread_T> *const &O, const typename UThreadC<Thread_T>::Handler &pH = 0 )
232  : pFN(pH), Data(P), Owner(O) {}
233 
236  UThreadC<Thread_T> * Owner;
237 
238  };
239 };
240 
242 // Explicit Specialization of void
243 //
244 template<>
245 class UTILITE_EXPORT UThreadC<void>
246 {
247  private:
248  struct Instance;
249 
250  public:
251  typedef THREAD_HANDLE Handle;
252  typedef void ( *Handler)();
253 
254  virtual ~UThreadC<void>() {}
255 
256  protected:
258 
259  virtual void ThreadMain() = 0;
260 
261  static void Exit()
262  { EXIT_THREAD; }
263 
264  static void TestCancel()
265  { Sleep(0); }
266 
267  static int Self()
268  {
269  return (int)GetCurrentThreadId();
270  //Handle Hnd = InvalidHandle;
271  //DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),(LPHANDLE)&Hnd,NULL,0,NULL);
272  //return Hnd;
273 
274  // only a pseudo-handle!
275  //return (Handle)GetCurrentThread();
276  }
277 
278  public:
279 
280  static int Create(
281  const Handler & Function,
282  Handle * const & H = 0,
283  const bool & CreateDetached = false,
284  const unsigned int & StackSize = 0,
285  const bool & CancelEnable = false, // UNUSED
286  const bool & CancelAsync = false // UNUSED
287  )
288  {
289  Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler_S,Function));
290 
291  if ( Hnd == CREATE_THREAD_FAILED )
292  {
293  if ( H ) *H = InvalidHandle;
294  return (int)CREATE_THREAD_ERROR;
295  }
296 
297  if ( H ) *H = Hnd;
298  if ( CreateDetached ) CLOSE_HANDLE(Hnd);
299  return 0;
300  }
301 
302  int Create(
303  Handle * const & H = 0,
304  const bool & CreateDetached = false,
305  const unsigned int & StackSize = 0,
306  const bool & CancelEnable = false, // UNUSED
307  const bool & CancelAsync = false // UNUSED
308  ) const
309  {
310  Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,this));
311 
312  if ( Hnd == CREATE_THREAD_FAILED )
313  {
314  if ( H ) *H = InvalidHandle;
315  return (int)CREATE_THREAD_ERROR;
316  }
317 
318  if ( H ) *H = Hnd;
319  if ( CreateDetached ) CLOSE_HANDLE(Hnd);
320  Self();
321  return 0;
322  }
323 
324  int Create(
325  unsigned long & ThreadId,
326  Handle * const & H = 0,
327  const bool & CreateDetached = false,
328  const unsigned int & StackSize = 0,
329  const bool & CancelEnable = false, // UNUSED
330  const bool & CancelAsync = false // UNUSED
331  ) const
332  {
333  *H = InvalidHandle;
334  int id;
335  *H = CREATE_THREAD2(StackSize,ThreadMainHandler,this, (LPDWORD)&id);
336  ThreadId = (unsigned long)id;
337 
338  if ( *H == CREATE_THREAD_FAILED )
339  {
340  *H = InvalidHandle;
341  return (int)CREATE_THREAD_ERROR;
342  }
343 
344  if ( CreateDetached ) CLOSE_HANDLE(*H);
345  return 0;
346  }
347 
348  static int Join( const Handle &H )
349  {
350  DWORD R = WaitForSingleObject((HANDLE)H,INFINITE);
351 
352  if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) )
353  {
354  CLOSE_HANDLE(H);
355  return 0;
356  }
357 
358  if ( R == WAIT_TIMEOUT ) return EAGAIN;
359  return EINVAL;
360  }
361 
362  static int Kill( const Handle &H )
363  { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; }
364 
365  static int Detach( const Handle &H )
366  { return (CLOSE_HANDLE(H)?0:EINVAL); }
367 
368  private:
369 
371  {
372  Param->ThreadMain();
373  Exit();
374  THREAD_RETURN(0);
375  }
376 
378  {
379  Param();
380  Exit();
381  THREAD_RETURN(0);
382  }
383 };
384 
385 #endif // !_U_Thread_Win32_
CREATE_THREAD_FAILED
#define CREATE_THREAD_FAILED
Definition: Win32/UThreadC.h:76
H
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange[ *:*] noreverse nowriteback set trange[ *:*] noreverse nowriteback set urange[ *:*] noreverse nowriteback set vrange[ *:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
UThreadC::Instance::pFN
UThreadC< Thread_T >::Handler pFN
Definition: Win32/UThreadC.h:234
UThreadC< void >::Join
static int Join(const Handle &H)
Definition: Win32/UThreadC.h:348
UThreadC::M_Create
static const UMutex & M_Create()
Definition: Win32/UThreadC.h:211
UThreadC::Instance::Instance
Instance(Thread_C_R P, UThreadC< Thread_T > *const &O, const typename UThreadC< Thread_T >::Handler &pH=0)
Definition: Win32/UThreadC.h:231
UThreadC::Thread_R
Thread_T & Thread_R
Definition: Win32/UThreadC.h:94
CREATE_THREAD_ERROR
#define CREATE_THREAD_ERROR
Definition: Win32/UThreadC.h:77
UThreadC::Detach
static int Detach(const Handle &H)
Definition: Win32/UThreadC.h:206
UThreadC< void >::TestCancel
static void TestCancel()
Definition: Win32/UThreadC.h:264
UThreadC< void >::Exit
static void Exit()
Definition: Win32/UThreadC.h:261
UThreadC::Create
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)
Definition: Win32/UThreadC.h:126
EXIT_THREAD
#define EXIT_THREAD
Definition: Win32/UThreadC.h:80
CREATE_THREAD
#define CREATE_THREAD(_S, _F, _P)
Definition: Win32/UThreadC.h:78
UThreadC< void >::Handle
THREAD_HANDLE Handle
Definition: Win32/UThreadC.h:248
CREATE_THREAD2
#define CREATE_THREAD2(_S, _F, _P, _ID)
Definition: Win32/UThreadC.h:79
UThreadC::Handle
THREAD_HANDLE Handle
Definition: Win32/UThreadC.h:100
UThreadC::Join
static int Join(const Handle &H)
Definition: Win32/UThreadC.h:189
UMutex
Definition: UMutex.h:54
UThreadC::UThreadC
UThreadC()
Definition: Win32/UThreadC.h:104
uSleep
void uSleep(unsigned int ms)
Definition: Win32/UThreadC.h:44
UThreadC< void >::Create
int Create(Handle *const &H=0, const bool &CreateDetached=false, const unsigned int &StackSize=0, const bool &CancelEnable=false, const bool &CancelAsync=false) const
Definition: Win32/UThreadC.h:302
UThreadC< void >::Create
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
Definition: Win32/UThreadC.h:324
UMutex.h
UWin32.h
UThreadC::Kill
static int Kill(const Handle &H)
Definition: Win32/UThreadC.h:203
THREAD_HANDLE
#define THREAD_HANDLE
Definition: Win32/UThreadC.h:74
UThreadC< void >::Self
static int Self()
Definition: Win32/UThreadC.h:267
THREAD_RETURN
#define THREAD_RETURN(x)
Definition: Win32/UThreadC.h:82
UThreadC< void >
Definition: Posix/UThreadC.h:226
UThreadC< void >::Kill
static int Kill(const Handle &H)
Definition: Win32/UThreadC.h:362
UThreadC
Definition: Posix/UThreadC.h:66
O
Key O(std::uint64_t j)
UThreadC::Instance::Data
UThreadC< Thread_T >::Thread_C_R Data
Definition: Win32/UThreadC.h:235
THREAD_RET_T
#define THREAD_RET_T
Definition: Win32/UThreadC.h:75
UThreadC< void >::Create
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)
Definition: Win32/UThreadC.h:280
PointMatcherSupport::Parametrizable
UThreadC::Self
static int Self()
Definition: Win32/UThreadC.h:114
id
id
USemaphore
Definition: USemaphore.h:54
USemaphore.h
UThreadC::Instance
Definition: Posix/UThreadC.h:210
UThreadC::Exit
static void Exit()
Definition: Win32/UThreadC.h:108
InvalidHandle
#define InvalidHandle
Definition: Win32/UThreadC.h:85
Eigen.Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor >
I
I
NULL
#define NULL
UThreadC< void >::ThreadMainHandler_S
static THREAD_RET_T THREAD_CALL ThreadMainHandler_S(Handler Param)
Definition: Win32/UThreadC.h:377
UThreadC< void >::ThreadMainHandler
static THREAD_RET_T THREAD_CALL ThreadMainHandler(UThreadC< void > *Param)
Definition: Win32/UThreadC.h:370
CLOSE_HANDLE
#define CLOSE_HANDLE(x)
Definition: Win32/UThreadC.h:81
UThreadC::Create
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
Definition: Win32/UThreadC.h:158
THREAD_CALL
#define THREAD_CALL
Definition: Win32/UThreadC.h:73
UThreadC< void >::ThreadMain
virtual void ThreadMain()=0
UThreadC::TestCancel
static void TestCancel()
Definition: Win32/UThreadC.h:111
UThreadC::S_Create
static const USemaphore & S_Create()
Definition: Win32/UThreadC.h:212
UThreadC< void >::Detach
static int Detach(const Handle &H)
Definition: Win32/UThreadC.h:365
UThreadC::ThreadMainHandler
static THREAD_RET_T THREAD_CALL ThreadMainHandler(Instance *Param)
Definition: Win32/UThreadC.h:214
S
S
R
R


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jul 25 2024 02:50:23