Организация ввода-вывода. Драйверы WDM. Рощин А.В. - 64 стр.

UptoLike

Составители: 

64
Функция IoCancelIrp устанавливает флаг Cancel в Irp. Затем она
проверяет, не равен ли NULL указатель CancelRoutine в IRP. Пока IRP
находится в очереди, CancelRoutine отличен от NULL. В этом случае
вызов IoCancelIrp приводит к вызову установленной функции отмены.
Функция отмены удаляет IRP из очереди, где он в данный момент
находится, и завершает IRP с кодом завершения STATUS_CANCELED.
После извлечения IRP из очереди функция IoCancelIrp обнаруживает,
что указатель CancelRoutine равен NULL, и вызывает функцию отмены.
IRP обрабатывается до завершения.
Когда нам приходится работать в реальных условиях многозадачности и
многопроцессорности, в которых следствия формально могут опережать
причины, может возникать множество ситуаций
«гонок» между постановкой в
очередь, удалением из очереди и функциями отмены.
Проблемы гонок могут решаться двумя путями. Во-первых, использование
собственной логики обработки очередей IRP. Во-вторых, использование функций
семейства IoCsqXxx, предлагаемых фирмой Microsoft. Использование этих
функций не предполагает понимания программистом их механизма работы.
Фирма предлагает использовать их «как есть».
Рассмотрим
примерный вид функции IoCancelIrp.
BOOLEAN IoCancelIrp(PIRP Irp)
{
IoAcquireCancelSpinLock(&Irp->CancelIrql); //1
&Irp->CancelIrql = TRUE; //2
PDRIVER_CANCEL CancelRoutine = IoSetCancelRoutine(Irp, NULL); //3
if (CancelRoutine)
{PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
(*CancelRoutine)(stack->DeviceObject, Irp); //4
return TRUE;
}
else
{
IoReleaseCancelSpinLock(Irp->CancelIrql);
return FALSE; //5
      − Функция IoCancelIrp устанавливает флаг Cancel в Irp. Затем она
        проверяет, не равен ли NULL указатель CancelRoutine в IRP. Пока IRP
        находится в очереди, CancelRoutine отличен от NULL. В этом случае
        вызов IoCancelIrp приводит к вызову установленной функции отмены.
        Функция отмены удаляет IRP из очереди, где он в данный момент
        находится, и завершает IRP с кодом завершения STATUS_CANCELED.
      − После извлечения IRP из очереди функция IoCancelIrp обнаруживает,
        что указатель CancelRoutine равен NULL, и вызывает функцию отмены.
        IRP обрабатывается до завершения.
      Когда нам приходится работать в реальных условиях многозадачности и
многопроцессорности, в которых следствия формально могут опережать
причины, может возникать множество ситуаций «гонок» между постановкой в
очередь, удалением из очереди и функциями отмены.
      Проблемы гонок могут решаться двумя путями. Во-первых, использование
собственной логики обработки очередей IRP. Во-вторых, использование функций
семейства IoCsqXxx, предлагаемых фирмой Microsoft. Использование этих
функций не предполагает понимания программистом их механизма работы.
Фирма предлагает использовать их «как есть».
      Рассмотрим примерный вид функции IoCancelIrp.
BOOLEAN IoCancelIrp(PIRP Irp)
 {
 IoAcquireCancelSpinLock(&Irp->CancelIrql);                   //1
 &Irp->CancelIrql = TRUE;                                     //2
 PDRIVER_CANCEL CancelRoutine = IoSetCancelRoutine(Irp, NULL); //3
 if (CancelRoutine)
 {PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
 (*CancelRoutine)(stack->DeviceObject, Irp);                  //4
 return TRUE;
  }
 else
  {
  IoReleaseCancelSpinLock(Irp->CancelIrql);
  return FALSE;                                               //5
                                      64