ReactOS 0.4.16-dev-297-gc569aee
fxsystemthread.hpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxSystemThread.hpp
8
9Abstract:
10
11 This class provides the safe handling for system threads
12 in the driver frameworks.
13
14
15Author:
16
17
18
19
20Revision History:
21
22--*/
23
24#ifndef _FXSYSTEMTHREAD_H_
25#define _FXSYSTEMTHREAD_H_
26
28
29private:
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 //
66 VOID
67 );
68
69public:
70
72 static
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
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
216private:
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
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_
unsigned char BOOLEAN
static VOID NTAPI SystemThread(_In_ PVOID Context)
LONG NTSTATUS
Definition: precomp.h:26
PVOID GetCOMWrapper()
Definition: fxobject.hpp:518
MdEThread m_PEThread
BOOLEAN CancelWorkItem(__inout PWORK_QUEUE_ITEM WorkItem)
_Must_inspect_result_ NTSTATUS CreateThread(VOID)
BOOLEAN QueueWorkItem(__inout PWORK_QUEUE_ITEM WorkItem)
BOOLEAN ExitThreadAsync(__inout FxSystemThread *Reaper)
static VOID STDCALL StaticThreadThunk(__inout PVOID Context)
WORK_QUEUE_ITEM m_Reaper
static VOID STDCALL StaticReaperThunk(__inout PVOID Context)
__inline BOOLEAN IsCurrentThread()
DECLARE_INTERNAL_NEW_OPERATOR()
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__deref_out FxSystemThread **SystemThread, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFDEVICE Device, __in MdDeviceObject DeviceObject)
virtual ~FxSystemThread(VOID)
BOOLEAN ExitThread(VOID)
LIST_ENTRY m_WorkList
static __inline MdEThread GetCurrentEThread()
Definition: mxgeneralkm.h:69
#define __in
Definition: dbghelp.h:35
#define __deref_out
Definition: dbghelp.h:26
#define __inout
Definition: dbghelp.h:50
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
static PVOID ptr
Definition: dispmode.c:27
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
Definition: typedefs.h:120
#define STDCALL
Definition: wdf.h:45
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FORCEINLINE
Definition: wdftypes.h:67
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
static void Initialize()
Definition: xlate.c:212