WdfInterruptTryToAcquireLock, fonction (wdfinterrupt.h)
[S’applique à KMDF et UMDF]
La méthode WdfInterruptTryToAcquireLock tente d’acquérir le verrou passif d’un objet d’interruption.
Syntaxe
BOOLEAN WdfInterruptTryToAcquireLock(
[in] WDFINTERRUPT Interrupt
);
Paramètres
[in] Interrupt
Handle vers un objet d’interruption de framework.
Valeur de retour
WdfInterruptTryToAcquireLock retourne TRUE s’il acquiert correctement le verrou de l’interruption. Sinon, la méthode retourne FALSE.
Remarques
Les pilotes qui utilisent gestion des interruptions de niveau passif appel WdfInterruptTryToAcquireLock pour démarrer une séquence de code qui s’exécute à IRQL = PASSIVE_LEVEL tout en maintenant le verrou d’interruption au niveau passif que le pilote a configuré dans la structure WDF_INTERRUPT_CONFIG de l’objet d’interruption.
WdfInterruptTryToAcquireLock tente d’acquérir le verrou, puis retourne immédiatement, qu’il ait acquis le verrou ou non. Si WdfInterruptTryToAcquireLock acquiert correctement le verrou, l’infrastructure appelle KeEnterCriticalRegion avant de retourner afin que les API de noyau normales soient désactivées.
Pour les objets d’interruption de niveau passif, les pilotes doivent appeler WdfInterruptTryToAcquireLock au lieu de WdfInterruptAcquireLock, lors de l’exécution dans un thread arbitraire, tel qu’une fonction de rappel d’objet file d’attente . Par exemple, le pilote peut appeler WdfInterruptTryToAcquireLock à partir de EvtIoRead. Cela évite la possibilité d’interblocage, comme décrit dans la section Remarques de WdfInterruptAcquireLock.
Lors de l’exécution dans un thread non arbitraire, tel qu’un élément de travail, le pilote doit utiliser WdfInterruptAcquireLock.
Lorsque le pilote appelle WdfInterruptReleaseLock, l’infrastructure libère le verrou d’interruption.
Exemples
L’exemple de code suivant montre comment une fonction de rappel EvtIoRead, exécutée dans un contexte arbitraire, peut appeler WdfInterruptTryToAcquireLock avant d’effectuer un travail lié à l’interruption. Si la méthode retourne FALSE, le pilote met en file d’attente un élément de travail pour effectuer le travail dans un thread non arbitraire. Le pilote fournit également une fonction de rappel EvtWorkItem qui appelle WdfInterruptAcquireLock avant d’effectuer le travail.
Dans cet exemple, le pilote a spécifié répartition séquentielle pour la file d’attente. Si le pilote spécifié toute autre méthode de répartition pour la file d’attente, le pilote doit utiliser une file d’attente manuelle supplémentaire pour conserver les demandes de traitement dans l’élément de travail. Les commentaires de code décrivent où ajouter cette prise en charge.
VOID EvtIoRead(
__in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t Length
)
{
DEVICE_CONTEXT devCtx;
devCtx = GetDeviceContext(WdfIoQueueGetDevice(Queue));
//
// Do any pre-acquiring interrupt lock work here.
//
//
// Check if we can acquire the lock.
//
if (WdfInterruptTryToAcquireLock(devCtx->InterruptObject) {
ReadFunctionLocked(Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(Request);
}
else {
WORK_ITEM_CONTEXT ctx;
ctx = GetWorkItemContext(ReadWorkItem);
ctx->Request = Request;
// If previous queue is non-sequential, call WdfRequestForwardToIoQueue
// to store request in an additional manual queue.
WdfWorkItemEnqueue(ReadWorkItem);
}
}
VOID
EvtReadWorkItemCallback(
WDFWORKITEM WorkItem
)
{
WORK_ITEM_CONTEXT wiCtx;
DEVICE_CONTEXT devCtx;
wiCtx = GetWorkItemContext(ReadWorkItem);
devCtx = GetDeviceContext(WdfWorkItemGetParentObject(WorkItem));
// If delivery queue is non-sequential, call WdfIoQueueRetrieveNextRequest
// to retrieve request that we stored in EvtIoRead.
//
// Acquire interrupt lock.
//
WdfInterruptAcquireLock(devCtx->InterruptObject);
ReadFunctionLocked(wiCtx->Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(wiCtx->Request);
}
Spécifications
Besoin | Valeur |
---|---|
plateforme cible | Universel |
version minimale de KMDF | 1.11 |
version minimale de UMDF | 2.0 |
En-tête | wdfinterrupt.h (include Wdf.h) |
Bibliothèque | Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF) |
IRQL | PASSIVE_LEVEL |
règles de conformité DDI | DriverCreate(kmdf) |