ReactOS 0.4.15-dev-7934-g1dc8d80
FxTimer Class Reference

#include <fxtimer.hpp>

Inheritance diagram for FxTimer:
Collaboration diagram for FxTimer:

Public Member Functions

 FxTimer (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxTimer (VOID)
 
_Must_inspect_result_ NTSTATUS Initialize (__in PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_TIMER_CONFIG Config, __in FxObject *ParentObject, __out WDFTIMER *Timer)
 
virtual BOOLEAN Dispose (VOID)
 
BOOLEAN Start (__in LARGE_INTEGER DueTime)
 
BOOLEAN Stop (__in BOOLEAN Wait)
 
VOID TimerHandler (VOID)
 
WDFOBJECT GetObject (VOID)
 
WDFTIMER GetHandle (VOID)
 
- 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 _Create (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_TIMER_CONFIG Config, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxObject *ParentObject, __out WDFTIMER *Timer)
 
- 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

VOID FlushAndRundown (VOID)
 

Private Attributes

MxTimer m_Timer
 
FxObjectm_Object
 
ULONG m_Period
 
ULONG m_TolerableDelay
 
BOOLEAN m_UseHighResolutionTimer
 
FxCallbackLockm_CallbackLock
 
FxObjectm_CallbackLockObject
 
PFN_WDF_TIMER m_Callback
 
FxSystemWorkItemm_SystemWorkItem
 
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
 
MxThread m_StopThread
 
BOOLEAN m_StopAgain
 
BOOLEAN m_StartAborted
 
BOOLEAN m_RunningDown
 

Static Private Attributes

static FN_WDF_SYSTEMWORKITEM _FxTimerWorkItemCallback
 
static MdDeferredRoutineType _FxTimerDpcThunk
 
static MdExtCallbackType _FxTimerExtCallbackThunk
 

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 42 of file fxtimer.hpp.

Constructor & Destructor Documentation

◆ FxTimer()

FxTimer::FxTimer ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 40 of file fxtimer.cpp.

42 :
43 FxNonPagedObject(FX_TYPE_TIMER, sizeof(FxTimer), FxDriverGlobals)
44{
45 m_Object = NULL;
46 m_Period = 0;
57
58 //
59 // Mark the object has having passive level dispose so that KeFlushQueuedDpcs
60 // can be called in Dispose().
61 //
63
65}
VOID MarkPassiveDispose(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:944
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
BOOLEAN m_StartAborted
Definition: fxtimer.hpp:117
FxObject * m_CallbackLockObject
Definition: fxtimer.hpp:83
ULONG m_TolerableDelay
Definition: fxtimer.hpp:65
MxThread m_StopThread
Definition: fxtimer.hpp:107
FxCallbackLock * m_CallbackLock
Definition: fxtimer.hpp:77
FxObject * m_Object
Definition: fxtimer.hpp:55
BOOLEAN m_RunningDown
Definition: fxtimer.hpp:122
ULONG m_Period
Definition: fxtimer.hpp:60
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
Definition: fxtimer.hpp:101
PFN_WDF_TIMER m_Callback
Definition: fxtimer.hpp:88
BOOLEAN m_StopAgain
Definition: fxtimer.hpp:112
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
@ ObjectDoNotLock
Definition: fxobject.hpp:128
@ FX_TYPE_TIMER
Definition: fxtypes.h:81

◆ ~FxTimer()

FxTimer::~FxTimer ( VOID  )
virtual

Definition at line 67 of file fxtimer.cpp.

68{
69 //
70 // If this hits, its because someone destroyed the TIMER by
71 // removing too many references by mistake without calling WdfObjectDelete
72 //
73 if (m_Object != NULL) {
76 "WDFTIMER %p destroyed without calling WdfObjectDelete, "
77 "or by Framework processing DeviceRemove. Possible reference count "
78 "problem?", GetObjectHandleUnchecked());
80 }
81
83}
PVOID __inline GetObjectHandleUnchecked(VOID)
Definition: fxobject.hpp:446
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define TRACINGDEVICE
Definition: dbgtrace.h:58
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define ASSERT(a)
Definition: mode.c:44
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27

Member Function Documentation

◆ _Create()

return FxTimer::_Create ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_TIMER_CONFIG  Config,
__in PWDF_OBJECT_ATTRIBUTES  Attributes,
__in FxObject ParentObject,
__out WDFTIMER *  Timer 
)
static

Definition at line 87 of file fxtimer.cpp.

94{
97
98 pFxTimer = new(FxDriverGlobals, Attributes) FxTimer(FxDriverGlobals);
99
100 if (pFxTimer == NULL) {
102 }
103
106 Config,
107 ParentObject,
108 Timer
109 );
110
111 if (!NT_SUCCESS(status)) {
113 }
114
115 return status;
116}
LONG NTSTATUS
Definition: precomp.h:26
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_Must_inspect_result_ NTSTATUS Initialize(__in PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_TIMER_CONFIG Config, __in FxObject *ParentObject, __out WDFTIMER *Timer)
Definition: fxtimer.cpp:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FxTimer * pFxTimer
Definition: fxtimerapi.cpp:234
Definition: ps.c:97
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

◆ Dispose()

BOOLEAN FxTimer::Dispose ( VOID  )
virtual

Reimplemented from FxObject.

Definition at line 458 of file fxtimer.cpp.

459{
460 KIRQL irql;
461
462 // MarkPassiveDispose() in Initialize ensures this
464
465 //
466 // Signal that we are running down.
467 //
468 Lock(&irql);
470 Unlock(irql);
471
472 //
473 // Cancel the timer, wait for its callback, then cleanup.
474 //
476
477 return TRUE;
478}
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID FlushAndRundown(VOID)
Definition: fxtimer.cpp:481
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define TRUE
Definition: types.h:120
KIRQL irql
Definition: wave.h:1
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

◆ FlushAndRundown()

VOID FxTimer::FlushAndRundown ( VOID  )
private

Definition at line 481 of file fxtimer.cpp.

496{
498
501 "Deleting WDFTIMER %p from with in the callback will "
502 "lead to deadlock, PRKTHREAD %p",
505 }
506
507 //
508 // Cancel the timer, wait for its callback.
509 //
510 Stop(TRUE);
511
512 //
513 // Delete will also wait for the workitem to exit.
514 //
515 if (m_SystemWorkItem != NULL) {
518 }
519
520 //
521 // Release our reference count to the associated parent object if present
522 //
523 if (m_Object != NULL) {
525 m_Object = NULL;
526
527 pObject->RELEASE(this);
528 }
529
530 //
531 // Perform our final release to ourselves, destroying the FxTimer
532 //
533 RELEASE(this);
534}
virtual VOID DeleteObject(VOID)
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
#define RELEASE(_tag)
Definition: fxobject.hpp:50
FxObject * pObject
_In_opt_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:241
#define GetHandle(h)
Definition: treelist.c:116

Referenced by Dispose().

◆ GetHandle()

WDFTIMER FxTimer::GetHandle ( VOID  )
inline

Definition at line 189 of file fxtimer.hpp.

192 {
193 return (WDFTIMER) GetObjectHandle();
194 }
return pObject GetObjectHandle()

◆ GetObject()

WDFOBJECT FxTimer::GetObject ( VOID  )
inline

Definition at line 176 of file fxtimer.hpp.

179 {
180 if( m_Object != NULL ) {
181 return m_Object->GetObjectHandle();
182 }
183 else {
184 return NULL;
185 }
186 }
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603

◆ Initialize()

_Must_inspect_result_ NTSTATUS FxTimer::Initialize ( __in PWDF_OBJECT_ATTRIBUTES  Attributes,
__in PWDF_TIMER_CONFIG  Config,
__in FxObject ParentObject,
__out WDFTIMER *  Timer 
)

Definition at line 120 of file fxtimer.cpp.

126{
128 IFxHasCallbacks* pCallbacks;
130 BOOLEAN isPassiveTimer;
131
133 pCallbacks = NULL;
134 isPassiveTimer = FALSE;
135
136 m_Period = Config->Period;
137
138 // Set tolerable delay.
139 if (Config->Size > sizeof(WDF_TIMER_CONFIG_V1_7)) {
140 m_TolerableDelay = Config->TolerableDelay;
141 }
142
143 if (Config->Size > sizeof(WDF_TIMER_CONFIG_V1_11)) {
144 m_UseHighResolutionTimer = Config->UseHighResolutionTimer;
145 }
146
147 // Set users callback function
148 m_Callback = Config->EvtTimerFunc;
149
150 //
151 // Decide whether to use the legacy KTimer or the new Ktimer2/ExTimer
152 // and call the appropriate initialization routine.
153 // The new ExTimers expose two kind of timers:no wake timers and the
154 // high resolution timers. For kernel mode, these timers are only exposed
155 // to new clients.
156 // For user mode,the underlying Threadpool APIs internally were upgraded
157 // to using the no wake timers and we don't expose the High
158 // resolution timers. Therefore the user mode code does not need to use
159 // the ex initialization.
160 //
161
162#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
163 // __REACTOS__ Ex timers are not supported
164 // if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,13)) {
165 // status = m_Timer.InitializeEx(this, FxTimer::_FxTimerExtCallbackThunk, m_Period,
166 // m_TolerableDelay, m_UseHighResolutionTimer);
167 // } else
168 {
170 }
171#else
173#endif
174
175 if (!NT_SUCCESS(status)) {
178 "Failed to initialize timer %!STATUS!", status);
179 return status;
180 }
181
182 //
183 // As long as we are associated, the parent object holds a reference
184 // count on the TIMER.
185 //
186 // We keep an extra reference count since on Dispose, we wait until
187 // all outstanding DPCs complete before allowing finalization.
188 //
189 // This reference must be taken early before we return any failure,
190 // since Dispose() expects this extra reference, and Dispose() will
191 // be called even if we return a failure status right now.
192 //
193 ADDREF(this);
194
195 m_DeviceBase = FxDeviceBase::_SearchForDevice(ParentObject, &pCallbacks);
196 if (m_DeviceBase == NULL) {
198 }
199
200 if (Attributes->ExecutionLevel == WdfExecutionLevelPassive) {
201 isPassiveTimer = TRUE;
202 }
203
204 //
205 // Configure Serialization for the callbacks on the supplied object.
206 //
208 ParentObject,
209 pCallbacks,
210 Config->AutomaticSerialization,
211 isPassiveTimer,
214 );
215
216 if (!NT_SUCCESS(status)) {
218
219
220
221
222
223
226 "ParentObject %p cannot automatically synchronize callbacks "
227 "with a Timer since it is configured for passive level callback "
228 "constraints. Set AutomaticSerialization to FALSE. %!STATUS!",
229 Attributes->ParentObject, status);
230 }
231
232 return status;
233 }
234
235 //
236 // If the caller wants passive callback then create a workitem.
237 //
238 if (isPassiveTimer) {
242 );
243 if (!NT_SUCCESS(status)) {
245 "Could not allocate workitem: %!STATUS!", status);
246 return status;
247 }
248 }
249
250 //
251 // We automatically synchronize with and reference count
252 // the lifetime of the framework object to prevent any TIMER races
253 // that can access the object while it is going away.
254 //
255
256 //
257 // The caller supplied object is the object the caller wants the
258 // TIMER to be associated with, and the framework must ensure this
259 // object remains live until the TIMER object is destroyed. Otherwise,
260 // it could access either object context memory, or an object API
261 // on a freed object.
262 //
263 // Due to the locking model of the framework, the lock may actually
264 // be owned by a higher level object as well. This is the lockObject
265 // returned. As long was we are a child of this object, the lockObject
266 // does not need to be dereferenced since it will notify us of Cleanup
267 // before it goes away.
268 //
269
270 //
271 // Associate the FxTimer with the object. When this object Cleans up, it
272 // will notify our Dispose function as well.
273 //
274
275 //
276 // Add a reference to the parent object we are associated with.
277 // We will be notified of Cleanup to release this reference.
278 //
279 ParentObject->ADDREF(this);
280
281 //
282 // Save the ptr to the object the TIMER is associated with
283 //
284 m_Object = ParentObject;
285
286 //
287 // Attributes->ParentObject is the same as ParentObject. Since we already
288 // converted it to an object, use that.
289 //
290 status = Commit(Attributes, (WDFOBJECT*)Timer, ParentObject);
291
292 if (!NT_SUCCESS(status)) {
293 return status;
294 }
295
296 return status;
297}
unsigned char BOOLEAN
static FxDeviceBase * _SearchForDevice(__in FxObject *Object, __out_opt IFxHasCallbacks **Callbacks)
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
CfxDevice * m_Device
Definition: fxobject.hpp:329
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)
Definition: fxobject.cpp:1044
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
MxTimer m_Timer
Definition: fxtimer.hpp:49
static MdDeferredRoutineType _FxTimerDpcThunk
Definition: fxtimer.hpp:213
BOOLEAN m_UseHighResolutionTimer
Definition: fxtimer.hpp:71
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in_opt PVOID TimerContext, __in MdDeferredRoutine TimerCallback, __in LONG Period)
Definition: mxtimerkm.h:119
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
@ WdfExecutionLevelPassive
Definition: wdfobject.h:54
#define STATUS_WDF_INCOMPATIBLE_EXECUTION_LEVEL
Definition: wdfstatus.h:198

Referenced by _Create().

◆ Start()

BOOLEAN FxTimer::Start ( __in LARGE_INTEGER  DueTime)

Definition at line 537 of file fxtimer.cpp.

558{
559 KIRQL irql;
562
563 Lock(&irql);
564
565 //
566 // Basic check to make sure timer object is not deleted. Note that this
567 // logic is not foolproof b/c someone may dispose the timer just after this
568 // validation and before the start routine queues the timer; but at least it
569 // is better than nothing.
570 //
571 if (m_RunningDown) {
573 "Calling WdfTimerStart when the timer object %p is"
574 " running down will lead to a crash",
575 GetHandle());
577 }
578 else if (m_StopThread != NULL) {
581 "WDFTIMER 0x%p is been stopped by PRKTHREAD 0x%p. "
582 "Ignoring the request to start timer",
584
585 //
586 // Let the stop thread know that we aborted this start operation.
587 //
589 }
590 else {
591 //
592 // Yes, the timer can be started.
593 //
595 }
596
597 Unlock(irql);
598
599 if (startTimer) {
600 //
601 // It may be possible for the timer to fire before the call from
602 // KeSetTimerEx completes. If this happens and if the timer callback
603 // disposes the timer object, a dispose work-item is queued.
604 // This work-item in turn may also run before KeSetTimerEx completes,
605 // making the object invalid by the time we try to take its Lock()
606 // below. This ADDREF() prevents the object from going away and it is
607 // matched by a RELEASE() when we are done.
608 //
609 ADDREF(this);
610
611 //
612 // Call the tolerable timer API only if OS supports it and driver
613 // requested it.
614 //
616
617 Lock(&irql);
618 if (m_StopThread != NULL) {
620 }
621 Unlock(irql);
622
623 //
624 // See ADDREF() comment above.
625 //
626 RELEASE(this);
627 }
628
629 return result;
630}
__inline BOOLEAN StartWithReturn(__in LARGE_INTEGER DueTime, __in ULONG TolerableDelay=0)
Definition: mxtimerkm.h:209
GLuint64EXT * result
Definition: glext.h:11304
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
static void startTimer(void)
Definition: xmllint.c:460

◆ Stop()

BOOLEAN FxTimer::Stop ( __in BOOLEAN  Wait)

Definition at line 633 of file fxtimer.cpp.

636{
637 KIRQL irql;
639#ifdef DBG
640 ULONG retryCount = 0;
641#endif
642
643 if (Wait) {
644 //
645 // If the caller specified wait, we will flush the queued DPC's
646 // to ensure any outstanding timer DPC has finished executing.
647 //
648 // The return value of timers is ambiguous in the case of periodic
649 // timers, so we flush whenever the caller desires to ensure all
650 // callbacks are complete.
651 //
652
653 //
654 // Make sure the stop is not called from within the callback
655 // because it's semantically incorrect and can lead to deadlock
656 // if the wait parameter is set.
657 //
661 "Calling WdfTimerStop from within the WDFTIMER "
662 "%p callback will lead to deadlock, PRKTHREAD %p",
665 return FALSE;
666 }
667
668 if (GetDriverGlobals()->FxVerifierOn) {
672 "WdfTimerStop(Wait==TRUE) called at IRQL > PASSIVE_LEVEL, "
673 "current IRQL = 0x%x", Mx::MxGetCurrentIrql());
675 return FALSE;
676 }
677 }
678
679 //
680 // Prevent the callback from restarting the timer.
681 //
682 Lock(&irql);
683
684 //
685 // Driver issue.
686 //
687 if (GetDriverGlobals()->IsVerificationEnabled(1, 9, OkForDownLevel) &&
688 m_StopThread != NULL) {
691 "Detected multiple calls to WdfTimerStop for "
692 "WDFTIMER 0x%p, stop in progress on PRKTHREAD 0x%p, "
693 "current PRKTHREAD 0x%p",
696 }
697
698 //
699 // Reset the flag to find out if the timer's start logic aborts
700 // b/c of this stop operation.
701 //
703
704 //
705 // This field is used for the following purposes:
706 // (a) Let the start thread know not to restart the timer while stop
707 // is running.
708 // (b) Detect concurrent calls to stop the timer.
709 // (c) To remember the thread id of the stopping thread.
710 //
712
713 do {
714#ifdef DBG
715 retryCount++;
716#endif
717 //
718 // Reset flag to catch when timer callback is restarting the
719 // timer.
720 //
722 Unlock(irql);
723
724 //
725 // Cancel the timer
726 //
727 result = m_Timer.Stop();
728
729 //
730 // Wait for the timer's DPC.
731 //
733
734 //
735 // Wait for the timer's passive work item.
736 //
737 if (m_SystemWorkItem != NULL) {
739 }
740
741 Lock(&irql);
742#ifdef DBG
743 //
744 // This loop is run for a max of 2 times.
745 //
746 ASSERT(retryCount < 3);
747#endif
748 //
749 // Re-stop timer if timer was not in queue and
750 // it got restarted in callback.
751 //
752 }while (result == FALSE && m_StopAgain);
753
754 //
755 // Stop completed.
756 //
759
760 //
761 // Return TRUE (i.e., timer in queue) if
762 // (a) stop logic successfully cancelled the timer or
763 // (b) the start logic aborted b/c of this stop.
764 //
765 if (m_StartAborted) {
766 result = TRUE;
768 }
769
770 Unlock(irql);
771 }
772 else {
773 //
774 // Caller doesn't want any synchronization.
775 // Cancel the timer.
776 //
777 result = m_Timer.Stop();
778 }
779
780 return result;
781}
_Must_inspect_result_ __inline BOOLEAN Stop(VOID)
Definition: mxtimerkm.h:273
__inline VOID FlushQueuedDpcs(VOID)
Definition: mxtimerkm.h:291
@ OkForDownLevel
Definition: fxglobals.h:80
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

◆ TimerHandler()

VOID FxTimer::TimerHandler ( VOID  )

Definition at line 300 of file fxtimer.cpp.

303{
305
306 if (m_Callback != NULL) {
307
308 //
309 // Save the current thread object pointer. We will use this avoid
310 // deadlock if the driver tries to delete or stop the timer from within
311 // the callback.
312 //
314
315 if (m_CallbackLock != NULL) {
316 KIRQL irql = 0;
317
321 }
322 else {
324 }
325
327 }
328}
virtual void Lock(__out PKIRQL PreviousIrql)=0
virtual void Unlock(__in KIRQL PreviousIrql)=0
FX_TRACK_DRIVER(fxDriverGlobals)

Member Data Documentation

◆ _FxTimerDpcThunk

VOID FxTimer::_FxTimerDpcThunk
staticprivate

Definition at line 213 of file fxtimer.hpp.

Referenced by Initialize().

◆ _FxTimerExtCallbackThunk

VOID FxTimer::_FxTimerExtCallbackThunk
staticprivate

Definition at line 217 of file fxtimer.hpp.

◆ _FxTimerWorkItemCallback

VOID FxTimer::_FxTimerWorkItemCallback
staticprivate

Definition at line 209 of file fxtimer.hpp.

◆ m_Callback

PFN_WDF_TIMER FxTimer::m_Callback
private

Definition at line 88 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and TimerHandler().

◆ m_CallbackLock

FxCallbackLock* FxTimer::m_CallbackLock
private

Definition at line 77 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and TimerHandler().

◆ m_CallbackLockObject

FxObject* FxTimer::m_CallbackLockObject
private

Definition at line 83 of file fxtimer.hpp.

Referenced by FxTimer(), and Initialize().

◆ m_CallbackThread

volatile POINTER_ALIGNMENT MxThread FxTimer::m_CallbackThread
private

Definition at line 101 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), Stop(), and TimerHandler().

◆ m_Object

FxObject* FxTimer::m_Object
private

Definition at line 55 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), GetObject(), Initialize(), and ~FxTimer().

◆ m_Period

ULONG FxTimer::m_Period
private

Definition at line 60 of file fxtimer.hpp.

Referenced by FxTimer(), and Initialize().

◆ m_RunningDown

BOOLEAN FxTimer::m_RunningDown
private

Definition at line 122 of file fxtimer.hpp.

Referenced by Dispose(), FxTimer(), and Start().

◆ m_StartAborted

BOOLEAN FxTimer::m_StartAborted
private

Definition at line 117 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_StopAgain

BOOLEAN FxTimer::m_StopAgain
private

Definition at line 112 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_StopThread

MxThread FxTimer::m_StopThread
private

Definition at line 107 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_SystemWorkItem

FxSystemWorkItem* FxTimer::m_SystemWorkItem
private

Definition at line 94 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), Initialize(), Stop(), and ~FxTimer().

◆ m_Timer

MxTimer FxTimer::m_Timer
private

Definition at line 49 of file fxtimer.hpp.

Referenced by Initialize(), Start(), and Stop().

◆ m_TolerableDelay

ULONG FxTimer::m_TolerableDelay
private

Definition at line 65 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and Start().

◆ m_UseHighResolutionTimer

BOOLEAN FxTimer::m_UseHighResolutionTimer
private

Definition at line 71 of file fxtimer.hpp.

Referenced by Initialize().


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