ReactOS  0.4.15-dev-3299-gbe8e5fc
fxsystemthread.hpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxSystemThread.hpp
8 
9 Abstract:
10 
11  This class provides the safe handling for system threads
12  in the driver frameworks.
13 
14 
15 Author:
16 
17 
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #ifndef _FXSYSTEMTHREAD_H_
25 #define _FXSYSTEMTHREAD_H_
26 
28 
29 private:
30 
33 
35 
37 
39 
40  // Used for Async thread spinup and reaping
41  //WORK_QUEUE_ITEM m_Spinup; // Async-Thread-Spinup
43 
46 
48  __in PFX_DRIVER_GLOBALS FxDriverGlobals
49  );
50 
51  //
52  // Create the system thread in order to be able to service work items
53  //
54  // It is recommended this is done from the system process context
55  // since the thread's handle is available to the user mode process
56  // for a temporary window. XP and later supports OBJ_KERNELHANDLE, but
57  // DriverFrameworks must support W2K with the same binary.
58  //
59  // It is safe to call this at DriverEntry which is in the system process
60  // to create an initial driver thread, and this driver thread should be
61  // used for creating any child driver threads on demand by using
62  // Initialize(FxSystemThread* SpinupThread).
63  //
64  BOOLEAN
65  Initialize(
66  VOID
67  );
68 
69 public:
70 
72  static
73  NTSTATUS
76  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
77  __in WDFDEVICE Device,
79  );
80 
81  virtual
83  VOID
84  );
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106  //
107  // This is called to tell the thread to exit.
108  //
109  // It must be called from thread context such as
110  // the driver unload routine since it will wait for the
111  // thread to exit.
112  //
113  // A worker thread will not exit unless it has processed
114  // all of its queued work items. If processing of queued
115  // workitems is no longer desired, then use CancelWorkItem
116  // to remove the items before calling this method.
117  //
118  BOOLEAN
119  ExitThread(
120  VOID
121  );
122 
123  //
124  // This is called to tell the thread to exit.
125  //
126  // This may be called from any context since it
127  // only signals the thread to exit, and does not
128  // wait for it. It is safe to release the object
129  // reference when this routine returns.
130  //
131  // This routine requires an FxSystemThread* to perform
132  // final thread reaping. This allows a driver to ensure that
133  // child threads have exited by waiting on their object pointer,
134  // before exiting a top level driver thread.
135  //
136  // This is required since a frameworks object that contains a
137  // system thread can be dereferenced, and thus destroyed
138  // in any context, so waiting may not be available. But unless
139  // a wait is done on the thread object pointer, no guarantee can be
140  // made that the thread has actually run and exited before
141  // the drivers code get unloaded, resulting in a system crash.
142  //
143  // Top level threads, such as the reaper, are exited using the
144  // ExitThread() synchronous call that waits for it to exit. This
145  // can be done in synchronous thread context such as DriverUnload
146  // time.
147  //
148  // If Synchronous threading is configured in the frameworks, the
149  // FxDriver object always contains a top level worker thread that
150  // may be used as the reaper, and DriverUnload synchronously waits
151  // for this thread to finish processing its work queue before
152  // exiting.
153  //
154  // A worker thread will not exit unless it has processed
155  // all of its queued work items. If processing of queued
156  // workitems is no longer desired, then use CancelWorkItem
157  // to remove the items before calling this method.
158  //
159  BOOLEAN
162  );
163 
164  //
165  // Queue a work item to the thread
166  //
167  // It is valid to queue work items before thread
168  // Initialize()/Initialize(FxSystemThread*) is called. The items
169  // remain queued until the system thread is started.
170  //
171  BOOLEAN
174  );
175 
176  //
177  // Attempt to cancel the work item.
178  //
179  // Returns TRUE if success.
180  //
181  // If returns FALSE, the work item
182  // routine either has been called, is running,
183  // or is about to be called.
184  //
185  BOOLEAN
188  );
189 
190  //
191  // Determine if current thread is this
192  // worker thread
193  //
194  __inline
195  BOOLEAN
197  {
198  return (Mx::GetCurrentEThread() == m_PEThread) ? TRUE : FALSE;
199  }
200 
202 
203 #ifdef INLINE_WRAPPER_ALLOCATION
204 #if (FX_CORE_MODE==FX_CORE_USER_MODE)
206  PVOID
208  )
209  {
210  PBYTE ptr = (PBYTE) this;
211  return (ptr + (USHORT) WDF_ALIGN_SIZE_UP(sizeof(*this), MEMORY_ALLOCATION_ALIGNMENT));
212  }
213 #endif
214 #endif
215 
216 private:
217 
218  //
219  // This is the thread's main processing function
220  //
221  VOID
222  Thread(
223  VOID
224  );
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239  //
240  // This is the reaper method
241  //
242  VOID
243  Reaper(
244  VOID
245  );
246 
248  NTSTATUS
249  CreateThread(
250  VOID
251  );
252 
253  //
254  // This is the thunk used to get from the system
255  // thread start callback into this class
256  //
257  static
258  VOID
259  STDCALL
262  );
263 
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279  //
280  // This thunk is called from the workitem in another
281  // thread that is reaping this thread
282  //
283  static
284  VOID
285  STDCALL
288  );
289 };
290 
291 #endif // _FXSYSTEMTHREAD_H_
BOOLEAN QueueWorkItem(__inout PWORK_QUEUE_ITEM WorkItem)
WORK_QUEUE_ITEM m_Reaper
static VOID STDCALL StaticReaperThunk(__inout PVOID Context)
#define TRUE
Definition: types.h:120
BOOLEAN Initialize(VOID)
LONG NTSTATUS
Definition: precomp.h:26
PVOID GetCOMWrapper()
Definition: fxobject.hpp:518
virtual ~FxSystemThread(VOID)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
BOOLEAN ExitThreadAsync(__inout FxSystemThread *Reaper)
#define FALSE
Definition: types.h:117
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
static VOID NTAPI SystemThread(_In_ PVOID Context)
static PVOID ptr
Definition: dispmode.c:27
unsigned char BOOLEAN
__inline BOOLEAN IsCurrentThread()
BOOLEAN ExitThread(VOID)
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__deref_out FxSystemThread **SystemThread, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFDEVICE Device, __in MdDeviceObject DeviceObject)
LIST_ENTRY m_WorkList
#define STDCALL
Definition: wdf.h:45
MdEThread m_PEThread
#define __inout
Definition: dbghelp.h:50
Definition: typedefs.h:119
FxSystemThread(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
static __inline MdEThread GetCurrentEThread()
Definition: mxgeneralkm.h:69
static VOID STDCALL StaticThreadThunk(__inout PVOID Context)
unsigned short USHORT
Definition: pedump.c:61
#define FORCEINLINE
Definition: wdftypes.h:67
DECLARE_INTERNAL_NEW_OPERATOR()
#define __deref_out
Definition: dbghelp.h:26
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
#define __in
Definition: dbghelp.h:35
BYTE * PBYTE
Definition: pedump.c:66
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
_Must_inspect_result_ NTSTATUS CreateThread(VOID)
BOOLEAN CancelWorkItem(__inout PWORK_QUEUE_ITEM WorkItem)