Utilisation de verrous d’infrastructure

Parfois, les pilotes doivent fournir une synchronisation spécifique au pilote des fonctions de rappel liées aux demandes d’E/S, en plus ou en remplacement de la synchronisation fournie par l’infrastructure. Les pilotes peuvent utiliser des verrous de synchronisation de rappel, des verrous de rotation, des verrous d’attente et des verrous d’interruption pour synchroniser le code du pilote.

Verrous de synchronisation de rappel

Si vous avez configuré votre pilote pour utiliser la fonctionnalité de synchronisation automatique de l’infrastructure, l’infrastructure acquiert un verrou de synchronisation avant d’appeler les fonctions de rappel d’événements liées aux demandes d’E/S du pilote.

Ces verrous de synchronisation de rappel, qui sont associés aux objets d’appareil framework et aux objets de file d’attente, peuvent également être acquis par les pilotes. Pour acquérir un verrou de synchronisation, un pilote appelle WdfObjectAcquireLock. Pour libérer le verrou, le pilote appelle WdfObjectReleaseLock.

Vous souhaiterez peut-être que votre pilote utilise les verrous de synchronisation de rappel si le pilote utilise la synchronisation au niveau de l’appareil ou de la file d’attente de l’infrastructure des fonctions de rappel liées aux demandes d’E/S, mais doit synchroniser du code qui s’exécute à IRQL = PASSIVE_LEVEL avec les fonctions de rappel qui s’exécutent à IRQL = DISPATCH_LEVEL. En effet, les pilotes peuvent utiliser la synchronisation automatique uniquement pour les fonctions de rappel qui s’exécutent au même IRQL.

Par exemple, un pilote peut utiliser la synchronisation automatique pour un objet d’élément de travail uniquement si le niveau d’exécution du parent de l’objet d’élément de travail est WdfExecutionLevelPassive (car la fonction de rappel d’un élément de travail s’exécute toujours à IRQL= PASSIVE_LEVEL). Par conséquent, si un pilote spécifie WdfExecutionLevelDispatch dans le membre ExecutionLevel de la structure WDF_OBJECT_ATTRIBUTES d’un objet d’appareil, le pilote ne peut pas définir le membre AutomaticSerialization de la structure de configuration d’un objet d’élément de travail enfant. Au lieu de cela, le pilote doit acquérir un verrou de synchronisation de rappel pour synchroniser les fonctions de rappel EvtWorkItem avec les fonctions de rappel de l’objet d’appareil parent.

Verrous d’attente du framework

Utilisez les verrous d’attente du framework pour synchroniser l’accès aux données du pilote à partir du code qui s’exécute à IRQL = PASSIVE_LEVEL. Avant qu’un pilote puisse utiliser un verrou d’attente du framework, il doit appeler WdfWaitLockCreate pour créer un objet wait-lock. Le pilote peut ensuite appeler WdfWaitLockAcquire pour acquérir le verrou et WdfWaitLockRelease pour le libérer.

Verrous de rotation de l’infrastructure

Utilisez des verrous de rotation du framework pour synchroniser l’accès aux données de pilote à partir du code qui s’exécute à IRQL <= DISPATCH_LEVEL. Lorsqu’un thread de pilote acquiert un verrou de rotation, le système définit l’IRQL du thread sur DISPATCH_LEVEL. Lorsque le thread libère le verrou, le système restaure l’IRQL du thread à son niveau précédent.

Un pilote qui n’utilise pas la synchronisation automatique du framework peut utiliser un verrou de rotation pour synchroniser l’accès à l’espace de contexte d’un objet d’appareil, si l’espace de contexte est accessible en écriture et si plusieurs fonctions de rappel d’événements du pilote accèdent à l’espace.

Avant qu’un pilote puisse utiliser un verrou de rotation du framework, il doit appeler WdfSpinLockCreate pour créer un objet spin-lock. Le pilote peut ensuite appeler WdfSpinLockAcquire pour acquérir le verrou et WdfSpinLockRelease pour le libérer.

Pour obtenir un exemple d’utilisation de verrous de rotation, consultez Synchronisation de l’annulation des demandes envoyées.

Verrous d’interruption d’infrastructure

Pour les objets d’interruption qui prennent en charge la gestion des interruptions DIRQL, les verrous d’interruption d’infrastructure sont des verrous de rotation. Une fois que votre pilote a acquis un verrou de rotation d’interruption, le pilote s’exécute au niveau du DIRQL de l’appareil jusqu’à ce qu’il libère le verrou. Pour plus d’informations sur l’utilisation des verrous d’interruption, consultez Synchronisation du code d’interruption.

Pour les objets d’interruption qui prennent en charge la gestion passive, les verrous d’interruption d’infrastructure sont des verrous d’attente. Une fois que votre pilote a acquis un verrou d’attente d’interruption, le pilote s’exécute à IRQL = PASSIVE_LEVEL jusqu’à ce qu’il libère le verrou. Pour plus d’informations sur la gestion au niveau passif, consultez Prise en charge des interruptions de niveau passif.