This Module allows Clients to scheduled work that will completed a SINGLE time, either for the duration of the Driver's runtime or persistent over reboots.
NOTE: A better name for this Module is "ScheduleTaskOnce".
typedef struct
{
// The Client Driver function that will perform work one time in a work item.
//
EVT_DMF_ScheduledTask_Callback* EvtScheduledTaskCallback;
// Client context for above callback used by the timer and by
// DMF_ScheduledTask__ExecuteNowDeferredEx Method.
//
VOID* CallbackContext;
// Indicates if the operation should be done every time driver loads or only a
// single time (persistent across reboots).
//
ScheduledTask_Persistence_Type PersistenceType;
// Indicates if the callback is executed immediately or is deferred.
//
ScheduledTask_ExecutionMode_Type ExecutionMode;
// Indicates when the callback is executed, D0Entry or PrepareHardware.
//
ScheduledTask_ExecuteWhen_Type ExecuteWhen;
// Retry timeout for ScheduledTask_WorkResult_SuccessButTryAgain.
//
ULONG TimerPeriodMsOnSuccess;
// Retry timeout for ScheduledTask_WorkResult_FailButTryAgain.
//
ULONG TimerPeriodMsOnFail;
// Delay before initial deferred call begins.
//
ULONG TimeMsBeforeInitialCall;
} DMF_CONFIG_ScheduledTask;
Member | Description |
---|---|
EvtScheduledTaskCallback | It is the Client callback that is executed. |
CallbackContext | it is the Client specific context that is passed to EvtScheduledTaskCallback. |
PersistenceType | Indicates whether or not the number of times EvtScheduledTaskCallback has executed is persistent across reboots or not. |
ExecutionMode | Indicates whether or not EvtScheduledTaskCallback executes in the caller's thread or a different thread. |
ExecuteWhen | Indicates when EvtScheduledTaskCallback should be called. |
TimerPeriodMsOnSuccess | The amount of time to wait in milliseconds until the EvtScheduledTaskCallback is called again in the case of a successful call. |
TimerPeriodMsOnFail | The amount of time to wait in milliseconds until the EvtScheduledTaskCallback is called again in the case of a failed call. |
TimeMsBeforeInitialCall | The amount of time to wait in milliseconds before the initial deferred call occurs. Default is zero milliseconds. |
typedef enum
{
ScheduledTask_WorkResult_Invalid,
ScheduledTask_WorkResult_Success,
ScheduledTask_WorkResult_Fail,
// Use in deferred case only.
//
ScheduledTask_WorkResult_FailButTryAgain,
ScheduledTask_WorkResult_SuccessButTryAgain
} ScheduledTask_Result_Type;
Member | Description |
---|---|
ScheduledTask_WorkResult_Success | Indicates that the Client callback succeeded. IMPORTANT: The callback will never be called again based on the |
the persistence type setting. | |
ScheduledTask_WorkResult_Fail | Indicates that the Client callback failed. |
ScheduledTask_WorkResult_FailButTryAgain | Indicates that the Client callback fails but that another attempt should be made automatically based on fail timer interval. |
ScheduledTask_WorkResult_SuccessButTryAgain | Indicates that the Client callback succeeded, but that another attempt should be made based on success timer interval. |
typedef enum
{
ScheduledTask_Persistence_Invalid,
// Only do the work one time ever.
//
ScheduledTask_Persistence_PersistentAcrossReboots,
// Do the work every time the Client starts.
//
ScheduledTask_Persistence_NotPersistentAcrossReboots
} ScheduledTask_Persistence_Type;
Member | Description |
---|---|
ScheduledTask_Persistence_PersistentAcrossReboots | It means that the number of times the callback has executed should be written to the registry so that the value is persistent across reboots. |
ScheduledTask_Persistence_NotPersistentAcrossReboots | It means that the number of times the callback has executed should not be written to the registry so that the value is not persistent across reboots. |
typedef enum
{
ScheduledTask_ExecuteWhen_Invalid,
// In PrepareHardware.
//
ScheduledTask_ExecuteWhen_PrepareHardware,
// In D0Entry.
//
ScheduledTask_ExecuteWhen_D0Entry,
// Not applicable for this Module. It means Client uses other Methods
// do other work.
//
ScheduledTask_ExecuteWhen_Other
} ScheduledTask_ExecuteWhen_Type;
Member | Description |
---|---|
ScheduledTask_ExecuteWhen_PrepareHardware | It means that the Client callback will try to execute from EvtDevicePrepareHardware callback. It may or may not actually execute depending on other attributes set during instantiation. |
ScheduledTask_ExecuteWhen_D0Entry | It means that the Client callback will try to execute from EvtDeviceD0Entry callback. It may or may not actually execute depending on other attributes set during instantiation. |
ScheduledTask_ExecuteWhen_Other | It means that the Client callback will execute neither in during PrepareHardware nor D0Exntry. |
typedef enum
{
ScheduledTask_ExecutionMode_Invalid,
ScheduledTask_ExecutionMode_Immediate,
ScheduledTask_ExecutionMode_Deferred
} ScheduledTask_ExecutionMode_Type;
Member | Description |
---|---|
ScheduledTask_ExecutionMode_Immediate | Indicates that the Client callback should be called in the thread of the caller. For example, if the caller is in EvtDevicePrepareHardware, this call will happen in the same thread. |
ScheduledTask_ExecutionMode_Deferred | Indicates that the Client callback should be called in a different thread than the caller. For example, if the caller is in EvtDevicePrepareHardware, this call will happen in a different thread. |
- None
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
ScheduledTask_Result_Type
EVT_DMF_ScheduledTask_Callback(
_In_ DMFModule DmfModule,
_In_ VOID* CallbackContext,
_In_ WDF_POWER_DEVICE_STATE PreviousState
);
This is the DMF_ScheduledTask Client callback that performs work on behalf of the Client. Depending on how the Module is instantiated, this Method may or not be called as necessary. This callback is also used with the Methods that cause this callback to execute on demand immediately or on demand deferred.
Important: It is possible that this callback can occur in two different threads during ReleaseHardware/D0Entry in cases when retries happen. It may be necessary to synchronize the code inside this callback.
Parameter | Description |
---|---|
ClientContext | Client driver specific context buffer. (This is usually a Client specific context which is the same for all calls.) |
CallbackContext | Client driver specific context buffer. (This is usually a Client specific context which is different for all calls.) |
PreviousState | Used when the callback is executed in D0Entry to tell the Client the previous power state. |
VOID
DMF_ScheduledTask_Cancel(
_In_ DMFModule DmfModule
);
Cancel any pending ScheduledTask Execution.
None
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
- Call
DMF_ScheduledTask_Cancel()
before callingWdfObjectDelete()
when a dynamic instance is used.
_Must_inspect_result_
ScheduledTask_Result_Type
DMF_ScheduledTask_ExecuteNow(
_In_ DMFModule DmfModule,
_In_ VOID* CallbackContext
);
This Method causes the deferred code to execute now. The deferred code will execute before this call completes.
NTSTATUS. Fails if the Request cannot be added to the queue.
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
CallbackContext | This is a Client specific context that is passed to the Client's deferred execution callback. |
- Is possible to use this Method from a Module's Close callback.
- In this case, the Client callback is called in the same thread.
_Must_inspect_result_
NTSTATUS
DMF_ScheduledTask_ExecuteNowDeferred(
_In_ DMFModule DmfModule,
_In_opt_ VOID* CallbackContext
);
IMPORTANT: Use DMF_ScheduledTask_ExecuteNowDeferredEx
instead of this Method.
This Method causes the deferred code to execute one time (at a later time). The deferred code will execute shortly after this call completes. The callback's return value is not honored using this Method (due to a an error in the logic).
NTSTATUS. Fails if the Request cannot be added to the queue.
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
CallbackContext | This is a Client specific context that is passed to the Client's deferred execution callback. |
- Is possible to use this Method from a Module's Close callback.
- It is possible to use this Method to execute code in a different thread. Sometimes, due to locking issues, this capability is needed.
- It is best to use the Ex version of this Method as it works intuitively.
- This Method is present to maintain compatibility with legacy Clients.
_Must_inspect_result_
NTSTATUS
DMF_ScheduledTask_ExecuteNowDeferredEx(
_In_ DMFModule DmfModule
);
This Method causes the deferred code to execute one time (at a later time). The deferred code will execute shortly after this call completes. The callback's return value is honored using this Method. The callback is passed the context specified in Module config.
NTSTATUS. Fails if the Request cannot be added to the queue.
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
- Is possible to use this Method from a Module's Close callback.
- It is possible to use this Method to execute code in a different thread. Sometimes, due to locking issues, this capability is needed.
- IMPORTANT: When the callback returns
ScheduledTask_WorkResult_Success
it means that the callback will never execute again.
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
DMF_ScheduledTask_Restart(
_In_ DMFMODULE DmfModule
);
This Method allows Client to schedule tasks after DMF_ScheduledTask_Cancel()
has been called.
None
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSTATUS
DMF_ScheduledTask_TimesRunGet(
_In_ DMFModule DmfModule,
_Out_ ULONG* TimesRun
);
This Method reads the default registry setting that keeps track of the number of times the DMF_ScheduledTask routine has executed.
NTSTATUS. Fails if the value cannot be read from the registry.
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
TimesRun | Returns the number of times the DMF_ScheduledTask routine has executed (the value read from the registry). |
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSTATUS
DMF_ScheduledTask_TimesRunSet(
_In_ DMFModule DmfModule,
_In_ ULONG TimesRun
);
This Method writes the default registry setting that keeps track of the number of times the DMF_ScheduledTask routine has executed to a given value.
NTSTATUS. Fails if the value cannot be written to the registry.
Parameter | Description |
---|---|
DmfModule | An open DMF_ScheduledTask Module handle. |
TimesRun | The given value to write to the registry. |
- None
- This Module is useful when it is necessary to execute code in a different thread due to locking constraints.
- None
- This Module implements a WDFTIMER and a WDFWORKITEM and uses either as needed.
- DMF_QueuedWorkItem
- Add support for a delay in the loop that executes all the deferred calls to prevent the processor from spinning for too long.
Task Execution