Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
199
Добавлен:
20.02.2016
Размер:
110.59 Кб
Скачать

[10.2.2.1.1] Обработка пакетов irp в функции StartIo

Как должна происходить обработка пакетов из системной очереди? Как уже говорилось, StartIo работает на уровне IRQL DISPATCH_LEVEL. Пока выполняется эта функция, ни один поток с более низким значением IRQL не может получить управление (если в системе один процессор). Следовательно, новые запросы в/в от прикладных программ попасть в очередь не могут (потоки не выполняются). Если завершение очередного пакета в/в всегда происходит в функции StartIo, системная очередь всегда содержит не более одного пакета в/в. Если пакет в/в не может быть обработан в тот момент, когда он попал в функцию StartIo, функция просто должна завершиться, не завершая запрос в/в и не вызывая IoStartNextPacket(). В этом случае устройство остается “занятым”.Поле pDeviceObject->DeviceQueue.Busy все еще TRUE, а в поле pDeviceObject->CurrentIrpнаходится указатель на этот пакет IRP. Такой пакет может быть обработан, например, при поступлении прерывания от аппаратного устройства (или при возникновении другого ожидаемого события). Функция, которая завершит обработку такого пакета, обязана вызвать IoStartNextPacket(), чтобы инициировать выборку очередного пакета из системной очереди. Заметим, что пока устройство остается “занятым”, функция StartIo для обработки пакетов из системной очереди не может быть вызвана.

Несмотря на простоту использования системной очереди, имеется существенное ограничение. Оно состоит в том, что очередь одна на все типы запросов в/в (чтение, запись, управление устройством). В каждый конкретный момент обрабатывается только какой-то один пакет IRP.

Могут быть ситуации, когда такое ограничение неприемлемо. Классическим примером является драйвер полнодуплексного устройства, которое одновременно позволяет как отправлять, так и получать данные. В этом случае необходимо начать обработку следующего запроса чтения при завершении текущего запроса чтения, и следующего запроса записи при завершении текущего запроса записи. При этом важно понимать, что в этом случае одновременно (т.е. в контекстах разных потоков) могут выполняться один запрос чтения и один запрос записи. Необходимы 2 очереди: одна – для запросов чтения, другая – для запросов записи.

[10.2.2.2] Очереди, управляемые драйвером

Вместо использования системной очереди, можно предусмотреть свой собственный механизм организации очереди. Это можно сделать двумя способами:

  • использовать для создания очереди функции управления очередью низкого уровня

  • использовать функции управления очередью высокого уровня. Этот способ очень редко используется и является промежуточным между использованием системной очереди и функций управления очередью низкого уровня.

Используя очереди, управляемые драйвером, драйвер получает полный контроль над очередью. Например, драйвер может организовать одновременную обработку трех запросов записи и двух запросов чтения при условии, что в данный момент не выполняется запрос управления устройством.

Как и в случае использования системной очереди, при получении пакета IRP, который необходимо поставить в очередь, такой пакет необходимо пометить как отложенный с помощью вызова IoMarkIrpPending(). Затем используется любой способ помещения указателя на пакет IRP в очередь.

Соседние файлы в папке Лабы по драйверам