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


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


/p>

Выполнение вызова IoStopTimer из функции IoTimerRoutine не допускается.

Для организации ожидания, более длительного, чем 1 секунда, можно организовать счетчик (например, внутри структуры расширения устройства), значение которого можно уменьшать (увеличивать) на единицу в самой функции IoTimerRoutine.

Работа с использованием callback-функции IoTimerRoutine может протекать следующим образом.

  • В процедуре AddDevice (DriverEntry) выполняется вызов IoInitializeTimer

    и связываются таймерная функция IoTimerRoutine и конкретный объект устройства.

  • В момент, когда вызывается драйверная рабочая процедура, предназначенная для обслуживания IRP_MJ_CREATE (то есть вызова Win API CreateFile), выполняется вызов IoStartTimer. Bce время, пока дескриптор доступа к драйверу (устройству) остается открытым, производятся вызовы функции IoTimerRoutine.
  • Каждый раз, когда производится вызов callback-процедуры IoTimerRoutine, значение счетчика таймерных "тиков" (если он задан) уменьшается (увеличивается) на единицу.
  • Когда пользовательская программа делает вызов CloseHandle, рабочая процедура драйвера, обслуживающая IRP_MJ_CLOSE, должна вызвать IoStopTimer, который прекратит вызовы функции IoTimerRoutine по сигналам таймера.

Разумеется, практически использовать собственно код callback-функции IoTimerRoutine можно весьма ограниченно, поскольку она стоит в стороне от "главных дорог" драйверных потоков. Как правило, при работе с этой функцией привлекаются еще DPC процедуры и/или другие синхронизационные примитивы (например, объекты события).

Рассмотрим несложный частный случай.

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

Дополняем структуру расширения объекта устройства счетчиком времени, оставшегося до наступления таймаута (превышения времени ожидания) с момента последнего прерывания, поступившего от обслуживаемого устройства:

typedef struct {

. . . LONG Remaining; // сколько еще осталось секунд . . . } MYDEVICE_EXTENSION, *PMYDEVICE_EXTENSION;




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