Программирование драйверов Windows


Интервалы ожидания для отдельного потока - часть 5


В процедуре AddDevice инициализируем таймер, связанный с данным объектом устройства. Значение счетчика не устанавливаем до момента реального запуска таймера.

NTSTATUS AddDevice ( IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT pDeviceObject ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pDeviceObject -&#62DeviceExtension; . . . IoInitializeTimer(pDeviceObject, MyIoTimerRoutine, pDevExt); . . . }

Рабочая процедура драйвера CreateRequestHandler вызывается, когда в пользовательском приложении была попытка доступа к устройству через Win API вызов CreateFile. В этот момент вполне можно запустить таймер. Он продолжает отсчеты до тех пор, пока дескриптор доступа к устройству из пользовательского приложения остается открытым. Поскольку таймер работает, а его отсчеты нам еще не нужны, то необходимо инициализировать таймер таким значением, которое показывало бы, что его можно игнорировать (это будет -1).

NTSTATUS CreateRequestHandler ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pDevObj-&#62DeviceExtension; . . . // ближе к концу инициализируем и запускаем таймер pDevExt-&#62Remaining = -1; IoStartTimer(pDevObj); . . . }

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

Использование системного вызова InterlockedExchange обеспечивает безопасное обновление и считывание 32-разрядного счетчика срабатываний таймера, который был ранее размещен в полностью определяемой разработчиком структуре расширения объекта устройства.




Начало  Назад  Вперед