ReactOS  0.4.15-dev-3017-g1d9542d
FxSystemThread Class Reference

#include <fxsystemthread.hpp>

Inheritance diagram for FxSystemThread:
Collaboration diagram for FxSystemThread:

Public Member Functions

virtual ~FxSystemThread (VOID)
 
BOOLEAN ExitThread (VOID)
 
BOOLEAN ExitThreadAsync (__inout FxSystemThread *Reaper)
 
BOOLEAN QueueWorkItem (__inout PWORK_QUEUE_ITEM WorkItem)
 
BOOLEAN CancelWorkItem (__inout PWORK_QUEUE_ITEM WorkItem)
 
__inline BOOLEAN IsCurrentThread ()
 
 DECLARE_INTERNAL_NEW_OPERATOR ()
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
virtual BOOLEAN Dispose (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Static Public Member Functions

static _Must_inspect_result_ NTSTATUS _CreateAndInit (__deref_out FxSystemThread **SystemThread, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFDEVICE Device, __in MdDeviceObject DeviceObject)
 
- Static Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Private Member Functions

 FxSystemThread (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
BOOLEAN Initialize (VOID)
 
VOID Thread (VOID)
 
VOID Reaper (VOID)
 
_Must_inspect_result_ NTSTATUS CreateThread (VOID)
 

Static Private Member Functions

static VOID STDCALL StaticThreadThunk (__inout PVOID Context)
 
static VOID STDCALL StaticReaperThunk (__inout PVOID Context)
 

Private Attributes

MxEvent m_InitEvent
 
MxEvent m_WorkEvent
 
LIST_ENTRY m_WorkList
 
PVOID m_ThreadPtr
 
MdEThread m_PEThread
 
WORK_QUEUE_ITEM m_Reaper
 
BOOLEAN m_Exit
 
BOOLEAN m_Initialized
 

Additional Inherited Members

- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Detailed Description

Definition at line 27 of file fxsystemthread.hpp.

Constructor & Destructor Documentation

◆ FxSystemThread()

FxSystemThread::FxSystemThread ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)
private

Definition at line 34 of file fxsystemthread.cpp.

36  :
37  FxNonPagedObject(FX_TYPE_SYSTEMTHREAD, 0, FxDriverGlobals)
38 {
39 
41  m_ThreadPtr = NULL;
42  m_Exit = FALSE;
43  m_PEThread = NULL;
44 
45  //m_Spinup.WorkerRoutine = NULL; // Async-Thread-Spinup
47 
51 }
WORK_QUEUE_ITEM m_Reaper
FxNonPagedObject(__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
#define FALSE
Definition: types.h:117
LIST_ENTRY m_WorkList
MdEThread m_PEThread
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: extypes.h:204
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112

Referenced by _CreateAndInit().

◆ ~FxSystemThread()

FxSystemThread::~FxSystemThread ( VOID  )
virtual

Definition at line 53 of file fxsystemthread.cpp.

53  {
54 
55 }

Member Function Documentation

◆ _CreateAndInit()

NTSTATUS FxSystemThread::_CreateAndInit ( __deref_out FxSystemThread **  SystemThread,
__in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in WDFDEVICE  Device,
__in MdDeviceObject  DeviceObject 
)
static

Definition at line 59 of file fxsystemthread.cpp.

65 {
67  FxSystemThread *pThread = NULL;
68 
69  *SystemThread = NULL;
70 
71  pThread = new(FxDriverGlobals) FxSystemThread(FxDriverGlobals);
72  if (pThread == NULL) {
74 
76  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
77  "WDFDEVICE 0x%p !devobj %p could not allocate a thread for handling "
78  "power requests %!STATUS!",
80 
81  return status;
82  }
83 
84  if (pThread->Initialize() == FALSE) {
86 
88  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
89  "WDFDEVICE 0x%p, !devobj %p, could not initialize power thread, "
90  "%!STATUS!",
92 
93  pThread->DeleteFromFailedCreate();
94 
95  return status;
96  }
97 
98  *SystemThread = pThread;
99 
101 
102  return status;
103 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN Initialize(VOID)
LONG NTSTATUS
Definition: precomp.h:26
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
static VOID NTAPI SystemThread(_In_ PVOID Context)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FxSystemThread(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by FxPkgPnp::CreatePowerThread().

◆ CancelWorkItem()

BOOLEAN FxSystemThread::CancelWorkItem ( __inout PWORK_QUEUE_ITEM  WorkItem)

Definition at line 408 of file fxsystemthread.cpp.

411 {
413  KIRQL irql;
414 
415  Lock(&irql);
416 
418 
419  while( Entry != &this->m_WorkList ) {
420 
421  if( Entry == &WorkItem->List ) {
422  RemoveEntryList(&WorkItem->List);
423  Unlock(irql);
424  return TRUE;
425  }
426 
427  Entry = Entry->Flink;
428  }
429 
430  // Not found
431  Unlock(irql);
432 
433  return FALSE;
434 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
KIRQL irql
Definition: wave.h:1
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY m_WorkList
Definition: typedefs.h:119
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
base of all file and directory entries
Definition: entries.h:82

◆ CreateThread()

NTSTATUS FxSystemThread::CreateThread ( VOID  )
private

Definition at line 141 of file fxsystemthread.cpp.

144 {
145  HANDLE threadHandle;
147 
148  //
149  // Take an extra object reference on ourselves to account
150  // for the system thread referencing the object while it is running.
151  //
152  // The thread itself will release this reference in its exit routine
153  //
155 
157  &threadHandle,
159  NULL, // Obja
160  NULL, // hProcess
161  NULL, // CLIENT_ID,
163  this
164  );
165 
166  if (!NT_SUCCESS(status)) {
168 
170  "Could not create system thread %!STATUS!", status);
171  //
172  // Release the reference taken above due to failure
173  //
175  }
176  else {
178  threadHandle,
180  NULL,
181  KernelMode,
182  &m_ThreadPtr,
183  NULL
184  );
185 
187 
188  // We can now close the thread handle since we have a pointer reference
189  ZwClose(threadHandle);
190  }
191 
192  return status;
193 }
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define RELEASE(_tag)
Definition: fxobject.hpp:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define FALSE
Definition: types.h:117
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
static VOID STDCALL StaticThreadThunk(__inout PVOID Context)
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by Initialize().

◆ DECLARE_INTERNAL_NEW_OPERATOR()

FxSystemThread::DECLARE_INTERNAL_NEW_OPERATOR ( )

◆ ExitThread()

BOOLEAN FxSystemThread::ExitThread ( VOID  )

Definition at line 238 of file fxsystemthread.cpp.

239 {
241  KIRQL irql;
242 
243  Lock(&irql);
244 
245  if( !m_Initialized ) {
246  Unlock(irql);
247  return TRUE;
248  }
249 
250  if( m_Exit ) {
251  ASSERT(FALSE); // This is not race free, so don't allow it
252  Unlock(irql);
253  return TRUE;
254  }
255 
256  // Tell the system thread to exit
257  m_Exit = TRUE;
258 
259  //
260  // The thread could still be spinning up, so we must handle this condition.
261  //
262  if( m_ThreadPtr == NULL ) {
263 
264  Unlock(irql);
265 
267 
268  // Wait for thread to start
270 
272 
275 
276  //
277  // Now we have a thread, wait for it to go away
278  //
279  ASSERT(m_ThreadPtr != NULL);
280  }
281  else {
282  Unlock(irql);
283  }
284 
285  m_WorkEvent.Set();
286 
287  //
288  // We can't be waiting in our own thread for the thread to exit.
289  //
291 
293 
294  // Wait for thread to exit
296  m_ThreadPtr,
297  Executive,
298  KernelMode,
299  FALSE,
300  NULL
301  );
302 
304 
307 
309 
310  //
311  // Now safe to unload the driver or object
312  // the thread worker is pointing to
313  //
314 
315  return TRUE;
316 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID Set()
Definition: mxeventkm.h:91
KIRQL irql
Definition: wave.h:1
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
__inline BOOLEAN IsCurrentThread()
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ __inline NTSTATUS WaitFor(__in KWAIT_REASON WaitReason, __in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in_opt PLARGE_INTEGER Timeout)
Definition: mxeventkm.h:115
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124

Referenced by FxPkgPnp::ReleasePowerThread().

◆ ExitThreadAsync()

BOOLEAN FxSystemThread::ExitThreadAsync ( __inout FxSystemThread Reaper)

Definition at line 319 of file fxsystemthread.cpp.

322 {
323  KIRQL irql;
324 
325  //
326  // Without a top level reaper, the frameworks can not ensure
327  // all worker threads have exited at driver unload in the async
328  // case. If this is a top level thread, then DriverUnload should
329  // call the synchronous ExitThread() method.
330  //
331  ASSERT(Reaper != NULL);
332 
333  Lock(&irql);
334 
335  if( !m_Initialized ) {
336  Unlock(irql);
337  return TRUE;
338  }
339 
340  if( m_Exit ) {
341  ASSERT(FALSE);
342  Unlock(irql);
343  return TRUE;
344  }
345 
346  // Tell the system thread to exit
347  m_Exit = TRUE;
348 
349  // Add a reference which will be released by the reaper
351 
352  Unlock(irql);
353 
354  m_WorkEvent.Set();
355 
357 
358  // We are the only user of this field protected by setting m_Exit
360  m_Reaper.Parameter = this;
361 
362  Reaper->QueueWorkItem(&m_Reaper);
363 
364  //
365  // It is not safe to unload the driver until the reaper
366  // thread has processed the work item and waited for this
367  // thread to exit.
368  //
369 
370  return TRUE;
371 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
WORK_QUEUE_ITEM m_Reaper
static VOID STDCALL StaticReaperThunk(__inout PVOID Context)
#define TRUE
Definition: types.h:120
__inline VOID Set()
Definition: mxeventkm.h:91
KIRQL irql
Definition: wave.h:1
volatile PVOID Parameter
Definition: extypes.h:205
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define ASSERT(a)
Definition: mode.c:44
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: extypes.h:204
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124

◆ Initialize()

BOOLEAN FxSystemThread::Initialize ( VOID  )
private

Definition at line 118 of file fxsystemthread.cpp.

119 {
121  KIRQL irql;
122 
123  Lock(&irql);
124 
125  // Frameworks bug if this is called with a thread already running
126  ASSERT(m_ThreadPtr == NULL);
127 
129 
131 
132  Unlock(irql);
133 
134  status = CreateThread();
135 
136  return NT_SUCCESS(status) ? TRUE : FALSE;
137 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ NTSTATUS CreateThread(VOID)
Definition: ps.c:97

Referenced by _CreateAndInit().

◆ IsCurrentThread()

__inline BOOLEAN FxSystemThread::IsCurrentThread ( )
inline

Definition at line 196 of file fxsystemthread.hpp.

197  {
198  return (Mx::GetCurrentEThread() == m_PEThread) ? TRUE : FALSE;
199  }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
MdEThread m_PEThread
static __inline MdEThread GetCurrentEThread()
Definition: mxgeneralkm.h:69

Referenced by ExitThread().

◆ QueueWorkItem()

BOOLEAN FxSystemThread::QueueWorkItem ( __inout PWORK_QUEUE_ITEM  WorkItem)

Definition at line 374 of file fxsystemthread.cpp.

377 {
378  KIRQL irql;
379  BOOLEAN result;
380 
381  Lock(&irql);
382 
383  if (m_Exit) {
384  result = FALSE;
385  }
386  else {
387  result = TRUE;
389 
390  m_WorkEvent.Set();
391  }
392 
393  Unlock(irql);
394 
395  return result;
396 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
GLuint64EXT * result
Definition: glext.h:11304
#define TRUE
Definition: types.h:120
__inline VOID Set()
Definition: mxeventkm.h:91
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
LIST_ENTRY m_WorkList
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110

◆ Reaper()

VOID FxSystemThread::Reaper ( VOID  )
private

Definition at line 584 of file fxsystemthread.cpp.

585 {
587  KIRQL irql;
588 
589  Lock(&irql);
590 
592  ASSERT(m_Exit);
593 
594  //
595  // The thread could still be spinning up, so we must handle this condition.
596  //
597  if( m_ThreadPtr == NULL ) {
598 
599  Unlock(irql);
600 
602 
603  // Wait for thread to start
605 
607 
610 
611  //
612  // Now we have a thread, wait for it to go away
613  //
614  ASSERT(m_ThreadPtr != NULL);
615  }
616  else {
617  Unlock(irql);
618  }
619 
621 
622  // Wait for thread to exit
624  m_ThreadPtr,
625  Executive,
626  KernelMode,
627  FALSE,
628  NULL
629  );
630 
632 
635 
637 
639 
640  return;
641 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
static VOID STDCALL StaticReaperThunk(__inout PVOID Context)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
KIRQL irql
Definition: wave.h:1
#define RELEASE(_tag)
Definition: fxobject.hpp:50
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ __inline NTSTATUS WaitFor(__in KWAIT_REASON WaitReason, __in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in_opt PLARGE_INTEGER Timeout)
Definition: mxeventkm.h:115
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124

Referenced by ExitThreadAsync().

◆ StaticReaperThunk()

VOID FxSystemThread::StaticReaperThunk ( __inout PVOID  Context)
staticprivate

Definition at line 668 of file fxsystemthread.cpp.

671 {
673 
674  thread->Reaper();
675 }
static HANDLE thread
Definition: service.c:33

Referenced by ExitThreadAsync(), and Reaper().

◆ StaticThreadThunk()

VOID FxSystemThread::StaticThreadThunk ( __inout PVOID  Context)
staticprivate

Definition at line 644 of file fxsystemthread.cpp.

647 {
649 
650  thread->Thread();
651 }
static HANDLE thread
Definition: service.c:33

Referenced by CreateThread(), and Thread().

◆ Thread()

VOID FxSystemThread::Thread ( VOID  )
private

Definition at line 437 of file fxsystemthread.cpp.

438 {
442  PWORK_QUEUE_ITEM pItem;
443 
444  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
445  // "Created, entering work loop");
446 
447  //
448  // The worker thread will process all list entries before
449  // checking for exit. This allows the top level FxDriver
450  // thread to process all deferred cleanup work items at
451  // driver unload.
452  //
453  // CancelWorkItem may be used to remove entries
454  // before requesting a thread exit if the caller wants to
455  // interrupt work queue processing.
456  //
457 
459 
460  // Initialize for IsCurrentThread()
462 
463  // Set the event that the thread now exists
464  m_InitEvent.Set();
465 
466  for ( ; ; ) {
467  KIRQL irql;
468 
469  //
470  // Lock the list so we are in sync with QueueWorkItem
471  //
472  Lock(&irql);
473 
474  while(!IsListEmpty(&m_WorkList)) {
475  //
476  // Instead of popping each LIST_ENTRY off of the old list and
477  // enqueueing it to the local list head, manipulate the first and
478  // last entry in the list to point to our new head.
479  //
480  head.Flink = m_WorkList.Flink;
481  head.Blink = m_WorkList.Blink;
482 
483  // First link in the list point backwrad to the new head
484  m_WorkList.Flink->Blink = &head;
485 
486  // Last link in the list point fwd to the new head
487  m_WorkList.Blink->Flink = &head;
488 
489  ASSERT(!IsListEmpty(&head));
490 
491  //
492  // Reinitialize the work list head
493  //
495 
496  //
497  // Process the workitems while unlocked so that the work item can
498  // requeue itself if needed and work at passive level.
499  //
500  Unlock(irql);
501 
502  while (!IsListEmpty(&head)) {
503  ple = RemoveHeadList(&head);
505  pItem->WorkerRoutine(pItem->Parameter);
506 
507  //
508  // NOTE: pItem may have been pool released by the called worker
509  // routine, so it may not be accessed after the callback
510  //
511  }
512 
513  //
514  // Relock the list and repeat until the work list is empty
515  //
516  Lock(&irql);
517  }
518 
519  // No more items on list, check for exit
520  if (m_Exit) {
521  //DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
522  // "Terminating");
523 
524  Unlock(irql);
525 
526  // Release the object reference held by the thread
528 
532 
533  // NOT REACHED
534  return;
535  }
536 
537  //
538  // No work to do, clear event under lock to prevent a race with a work
539  // enqueue
540  //
541  m_WorkEvent.Clear();
542 
543  Unlock(irql);
544 
545  // We are a system thread, so we do not need KeEnterCriticalRegion()
548 
551  }
552 
553  // NOT REACHED
554  return;
555 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID Set()
Definition: mxeventkm.h:91
KIRQL irql
Definition: wave.h:1
#define RELEASE(_tag)
Definition: fxobject.hpp:50
volatile PVOID Parameter
Definition: extypes.h:205
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
__inline VOID Clear()
Definition: mxeventkm.h:102
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_Must_inspect_result_ __inline NTSTATUS WaitFor(__in KWAIT_REASON WaitReason, __in KPROCESSOR_MODE WaitMode, __in BOOLEAN Alertable, __in_opt PLARGE_INTEGER Timeout)
Definition: mxeventkm.h:115
LIST_ENTRY m_WorkList
#define ASSERT(a)
Definition: mode.c:44
MdEThread m_PEThread
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: extypes.h:204
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
static __inline MdEThread GetCurrentEThread()
Definition: mxgeneralkm.h:69
static VOID STDCALL StaticThreadThunk(__inout PVOID Context)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1144
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Member Data Documentation

◆ m_Exit

BOOLEAN FxSystemThread::m_Exit
private

◆ m_InitEvent

MxEvent FxSystemThread::m_InitEvent
private

Definition at line 31 of file fxsystemthread.hpp.

Referenced by ExitThread(), FxSystemThread(), Reaper(), and Thread().

◆ m_Initialized

BOOLEAN FxSystemThread::m_Initialized
private

◆ m_PEThread

MdEThread FxSystemThread::m_PEThread
private

Definition at line 38 of file fxsystemthread.hpp.

Referenced by FxSystemThread(), IsCurrentThread(), and Thread().

◆ m_Reaper

WORK_QUEUE_ITEM FxSystemThread::m_Reaper
private

Definition at line 42 of file fxsystemthread.hpp.

Referenced by ExitThreadAsync(), and FxSystemThread().

◆ m_ThreadPtr

PVOID FxSystemThread::m_ThreadPtr
private

Definition at line 36 of file fxsystemthread.hpp.

Referenced by CreateThread(), ExitThread(), FxSystemThread(), Initialize(), and Reaper().

◆ m_WorkEvent

MxEvent FxSystemThread::m_WorkEvent
private

Definition at line 32 of file fxsystemthread.hpp.

Referenced by ExitThread(), ExitThreadAsync(), FxSystemThread(), QueueWorkItem(), and Thread().

◆ m_WorkList

LIST_ENTRY FxSystemThread::m_WorkList
private

Definition at line 34 of file fxsystemthread.hpp.

Referenced by CancelWorkItem(), FxSystemThread(), QueueWorkItem(), and Thread().


The documentation for this class was generated from the following files: