uLib  User mode C/C++ extended API library for Win32 programmers.
Thread.h
Go to the documentation of this file.
1 //==---------------------------------------------------------------------------
2 // Project: uLib utility library.
3 // Module: Threads that can be safely killed (unlike TerminateThread).
4 // License: Released under the NNOSL (See NNOSL.txt in the base directory).
5 //
6 // Author: Love Nystrom 2017 <neo.love@hotmail.com>
7 // Author: Based on code by Jeff Richter 1995, published in MSJ March 1996.
8 //
9 // Jeff's article contains the following disclaimer:
10 //
11 // The information contained herein is not endorsed by Microsoft.
12 // Microsoft makes no warranty as to the accuracy or the completeness of the
13 // information. Users are advised that they use this at their own risk.
14 //
15 //==---------------------------------------------------------------------------
16 // NOTE: Thread uses _beginthreadex to start the thread,
17 // in order to be safe/r with the multithread C runtime library.
18 // Ergo, end your thread function by returning, never by ExitThread, and never
19 // kill a Thread with TerminateThread, use Stop (which calls Kill if needed).
20 //==---------------------------------------------------------------------------
21 // NOTE: Requires /EHa compiler switch to perform stack unwind correctly.
22 //==---------------------------------------------------------------------------
23 
24 #ifdef __cplusplus
25 #ifndef __Thread_h_incl__
26 #define __Thread_h_incl__
27 
28 #include <uLib/Common.h>
29 #include <Process.h>
30 
31 #ifdef __GNUC__ // MinGW misses these declarations
32  typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(
33  LPVOID lpThreadParameter
34  );
35  #ifndef ERROR_DBG_RIPEXCEPTION
36  #define ERROR_DBG_RIPEXCEPTION 695L
37  #endif
38 #endif
39 
40 BEGIN_NAMESPACE( uLib ) // Because "Thread" is such an inconspicous Id.
41 
42 //==---------------------------------------------------------------------------
66 //==---------------------------------------------------------------------------
68 
69 //==---------------------------------------------------------------------------
70 // SimpleThread
71 //==---------------------------------------------------------------------------
72 
73 typedef class SimpleThread* PSimpleThread;
74 
87 
88 class SimpleThread {
89 public:
90  PVOID UserData;
91  HANDLE hThread;
92  volatile DWORD Id;
93 
94  SimpleThread();
95  virtual ~SimpleThread();
96 
99 
100  bool Start( PTHREAD_START_ROUTINE ThrFunc, DWORD msYield = 100 );
101 
105 
106  bool Stop( DWORD msWait = 3000 );
107 
109 
110  void Close();
111 };
112 
113 #ifndef HAVE_STRUCTURED_EH
114 // Sorry: So far, I can't get SEH to work with any of my GCC..
115 // Until I (or some contributor) can, Thread is only available for MSVC and Borland builds.
116 #else
117 //==---------------------------------------------------------------------------
118 // Thread
119 //==---------------------------------------------------------------------------
120 
121 typedef class Thread* PThread;
122 
131 
132 class Thread {
133 public:
134  PVOID UserData;
135  HANDLE hThread;
136  volatile DWORD idThread;
137 
149 
150  Thread(
151  PTHREAD_START_ROUTINE pFunc,
152  SIZE_T StackSize = 0,
153  DWORD Flags = 0,
154  PSECURITY_ATTRIBUTES pSec = NULL
155  );
156  virtual ~Thread();
157 
160 
161  bool SetThreadProc( PTHREAD_START_ROUTINE pFunc );
162 
165 
166  bool Start();
167 
172 
173  bool Stop( DWORD msWait, bool mayNuke = false );
174 
176 
177  bool Pause( bool pause );
178 
181 
182  bool Kill();
183 
186 
187  void DelayDeath( bool enable );
188 
189 protected:
196 
197  virtual DWORD Execute() { return _ThreadFunc( this ); } // Invoke user's function
198 
199  PTHREAD_START_ROUTINE _ThreadFunc;
200  PSECURITY_ATTRIBUTES _SecAttr;
201  SIZE_T _StkSize;
203 
204 private:
205  HANDLE _hmControl; // Mutex to coordinate access the other objects.
206  HANDLE _hmDelay; // Mutex to queue killing when owned.
207  HANDLE _heEnd; // Event to signal that killing was queued.
208 
209  volatile DWORD _DelayCount; // Nesting count for DelayDeath.
210 
211  #ifdef INCL_THREAD_W95_SUPPORT
212  PVOID _pThunk; // Pointer to the SEH thunks.
213  HANDLE _hFileMap; // File mapping handle.
214  static DWORD _TLSIndex; // Gives static _ForceDeath access to 'this'.
215  #endif
216 
217  void _Cleanup( bool closeThr = false ); // Close handles.
218  static void _ForceDeath( void ); // Raise an exception in the thread.
219  static THREADPROC _TProc( PVOID Arg ); // Crucial wrapper.
221 };
222 
223 #endif//def HAVE_STRUCTURED_EH
226 #endif//ndef __Thread_h_incl__
227 #endif//def __cplusplus
228 // EOF
unsigned long DWORD
Definition: Common.h:414
virtual DWORD Execute()
Definition: Thread.h:197
PVOID UserData
Definition: Thread.h:134
#define END_NAMESPACE(name)
Definition: Common.h:225
HANDLE hThread
Definition: Thread.h:91
#define THREADPROC
Definition: Common.h:1114
Definition: DynArray.h:18
volatile DWORD idThread
Definition: Thread.h:136
DWORD _Flags
Definition: Thread.h:202
PTHREAD_START_ROUTINE _ThreadFunc
Definition: Thread.h:199
volatile DWORD Id
Definition: Thread.h:92
HANDLE hThread
Definition: Thread.h:135
class SimpleThread * PSimpleThread
Definition: Thread.h:73
#define BEGIN_NAMESPACE(name)
Definition: Common.h:224
Common include; Added types, small "ubiquitous" utilities, et c.
PVOID UserData
Definition: Thread.h:90
PSECURITY_ATTRIBUTES _SecAttr
Definition: Thread.h:200
SIZE_T _StkSize
Definition: Thread.h:201
class Thread * PThread
Definition: Thread.h:121