Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
[Применимо к KMDF и UMDF]
Метод WdfInterruptTryToAcquireLock пытается получить пассивный блок объекта прерывания.
Синтаксис
BOOLEAN WdfInterruptTryToAcquireLock(
[in] WDFINTERRUPT Interrupt
);
Параметры
[in] Interrupt
Дескриптор объекта прерывания платформы.
Возвращаемое значение
WdfInterruptTryToAcquireLock возвращает значение TRUE, если он успешно получает блокировку прерывания. В противном случае метод возвращает ЗНАЧЕНИЕ FALSE.
Замечания
Драйверы, использующие обработку прерываний на пассивном уровне вызов WdfInterruptTryToAcquireLock для запуска последовательности кода, выполняемой на IRQL = PASSIVE_LEVEL при сохранении блокировки прерываний на пассивном уровне, настроенной драйвером в WDF_INTERRUPT_CONFIG структуре объекта прерывания.
WdfInterruptTryToAcquireLock пытается получить блокировку, а затем немедленно возвращается, приобрел ли он блокировку или нет. Если WdfInterruptTryToAcquireLock успешно получает блокировку, платформа вызывает KeEnterCriticalRegion перед возвратом, чтобы обычные API ядра были отключены.
Для объектов прерываний на пассивном уровне драйверы должны вызывать WdfInterruptTryToAcquireLock вместо WdfInterruptAcquireLockпри выполнении в произвольном потоке, например функции обратного вызова объекта очереди . Например, драйвер может вызывать WdfInterruptTryToAcquireLock из EvtIoRead. Это позволяет избежать взаимоблокировки, как описано в разделе "Замечания" WdfInterruptAcquireLock.
При выполнении в необорчивом потоке, например рабочий элемент, драйвер должен использовать WdfInterruptAcquireLock.
Когда драйвер вызывает WdfInterruptReleaseLock, платформа освобождает блокировку прерываний.
Примеры
В следующем примере кода показано, как функция обратного вызова EvtIoRead, выполняемая в произвольном контексте, может вызывать WdfInterruptTryToAcquireLock перед выполнением работы, связанной с прерыванием. Если метод возвращает значение FALSE, драйвер помещает рабочий элемент в очередь для выполнения работы в неопроверяемом потоке. Драйвер также предоставляет функцию обратного вызова EvtWorkItem, которая вызывает WdfInterruptAcquireLock перед выполнением работы.
В этом примере драйвер указал последовательную отправку очереди. Если драйвер, указанный любой другой метод отправки для очереди, драйвер должен использовать дополнительную очередь вручную для хранения запросов на обработку в рабочем элементе. Примечания кода описывают место добавления такой поддержки.
VOID EvtIoRead(
__in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t Length
)
{
DEVICE_CONTEXT devCtx;
devCtx = GetDeviceContext(WdfIoQueueGetDevice(Queue));
//
// Do any pre-acquiring interrupt lock work here.
//
//
// Check if we can acquire the lock.
//
if (WdfInterruptTryToAcquireLock(devCtx->InterruptObject) {
ReadFunctionLocked(Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(Request);
}
else {
WORK_ITEM_CONTEXT ctx;
ctx = GetWorkItemContext(ReadWorkItem);
ctx->Request = Request;
// If previous queue is non-sequential, call WdfRequestForwardToIoQueue
// to store request in an additional manual queue.
WdfWorkItemEnqueue(ReadWorkItem);
}
}
VOID
EvtReadWorkItemCallback(
WDFWORKITEM WorkItem
)
{
WORK_ITEM_CONTEXT wiCtx;
DEVICE_CONTEXT devCtx;
wiCtx = GetWorkItemContext(ReadWorkItem);
devCtx = GetDeviceContext(WdfWorkItemGetParentObject(WorkItem));
// If delivery queue is non-sequential, call WdfIoQueueRetrieveNextRequest
// to retrieve request that we stored in EvtIoRead.
//
// Acquire interrupt lock.
//
WdfInterruptAcquireLock(devCtx->InterruptObject);
ReadFunctionLocked(wiCtx->Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(wiCtx->Request);
}
Требования
| Требование | Ценность |
|---|---|
| целевая платформа | универсальный |
| минимальная версия KMDF | 1.11 |
| минимальная версия UMDF | 2.0 |
| Заголовок | wdfinterrupt.h (include Wdf.h) |
| Библиотека | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
| IRQL | PASSIVE_LEVEL |
| правил соответствия DDI | DriverCreate(kmdf) |