Поделиться через


Методы диспетчеризации для запросов ввода-вывода

Когда драйвер вызывает WdfIoQueueCreate для создания очереди ввода-вывода, он указывает метод диспетчеризации для очереди. Платформа предоставляет три метода диспетчеризации: последовательный, параллельный и ручной. Драйвер может указать любой из этих методов диспетчеризации для любой очереди ввода-вывода, включая очередь ввода-вывода устройства по умолчанию.

Драйвер задает метод диспетчеризации очереди, указывая WDF_IO_QUEUE_DISPATCH_TYPE типизированное значение в структуре WDF_IO_QUEUE_CONFIG очереди.

Примеры использования каждого метода диспетчеризации см. в разделе Примеры использования очередей ввода-вывода.

Последовательная диспетчеризация

Если драйвер или устройство могут обрабатывать только один запрос ввода-вывода из очереди за раз, следует настроить очереди ввода-вывода устройства для использования последовательной диспетчеризации, которая также называется синхронной диспетчеризированием. При таком типе диспетчеризации платформа доставляет запросы драйверу по одному. Платформа не доставляет следующий запрос, пока драйвер не завершит, не отменит или повторно отправляет предыдущий запрос.

После того как платформа доставляет запрос одному из обработчиков запросов драйвера, драйвер обрабатывает запрос. Если драйвер перенаправит запрос в общий целевой объект ввода-вывода, он обычно вызывает один из синхронных методов целевого объекта ввода-вывода. Дополнительные сведения об этих методах см. в статье Синхронная отправка запросов ввода-вывода. В конечном итоге драйвер должен завершить или отменить каждый запрос, получаемый из очереди ввода-вывода.

Драйвер, настроив очередь ввода-вывода для последовательной диспетчеризации, может вызвать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject , чтобы получить еще один запрос из очереди до завершения или отмены последнего полученного запроса. Это может потребоваться сделать в драйвере функции, чтобы драйвер мог запустить следующую аппаратную операцию, пока функция обратного вызова EvtInterruptDpc драйвера по-прежнему обрабатывает данные из предыдущей аппаратной операции.

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

Параллельная диспетчеризация

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

Если драйвер настраивает очередь ввода-вывода для использования параллельной диспетчеризации, платформа доставляет драйверу запросы ввода-вывода, как только они становятся доступными в очереди. В результате драйверу может потребоваться обрабатывать несколько запросов одновременно.

Каждый раз, когда один из обработчиков запросов драйвера получает запрос, драйвер должен обработать запрос , а затем завершить запрос. Если драйвер перенаправит запрос в общий целевой объект ввода-вывода, он обычно вызывает один из асинхронных методов целевого объекта ввода-вывода. Дополнительные сведения об этих методах см. в статье Отправка запросов ввода-вывода асинхронно. В конечном итоге драйвер должен завершить или отменить каждый запрос, получаемый из очереди ввода-вывода.

Драйвер, использующий параллельную диспетчеризацию, может вызвать WdfIoQueueStop или WdfIoQueueStopSynchronous, чтобы временно остановить очередь, а затем вызвать WdfIoQueueStart для перезапуска очереди.

Диспетчеризация вручную

Если вы хотите, чтобы драйвер полностью контролировал доставку запросов ввода-вывода, вы можете настроить очередь ввода-вывода устройства для использования ручной диспетчеризации, что означает, что платформа не доставляет запросы драйверу, если драйвер явно не запрашивает их.

Чтобы получить запрос из очереди вручную, драйвер может вызвать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject в цикле, который опрашивает очередь. Кроме того, драйвер может вызвать WdfIoQueueReadyNotify для регистрации функции обратного вызова, которую будет вызывать платформа, когда один или несколько запросов доступны в очереди. После того как платформа вызывает функцию обратного вызова, драйвер может вызвать WdfIoQueueRetrieveNextRequest или WdfIoQueueRetrieveRequestByFileObject в цикле для получения запросов.

После того как драйвер получит запрос из очереди, он должен обработать запрос. В конечном итоге драйвер должен завершить или отменить каждый запрос.