Запрос на владение мьютексом выполняется вызовом KeWaitForSingleObject
либо вызовом KeWaitForMultipleObject из кода, работающего на уровне IRQL равном PASSIVE_LEVEL. Специально для мьютексов придумано также макроопределение KeWaitForMutexObject, которое есть текстуальная подстановка все того же системного вызова KeWaitForSingleObject.
Единственная функция, которую можно вызывать из кода уровня IRQL выше, чем PASSIVE_LEVEL, — это вызов KeReadStateMutex (таблица 10.36).
Таблица 10.36. Прототип вызова KeReadStateMutex
LONG KeReadStateMutex | IRQL <= DISPATCH_LEVEL |
Параметры | Возвращает состояние объекта мьютекса |
IN PKMUTEX pMutex | Указатель на объект мьютекса |
Возвращаемое значение |
1, если объект мьютекса находится в сигнальном состоянии |
Описанные выше простые мьютексы применяются теперь не так широко, как быстрые мьютексы, которые рассмотрены ниже.
Быстрый мьютекс (fast mutex) — это синхронизационный объект, который работает практически так же, как и описанный выше обычный мьютекс режима ядра, однако не допускает повторных (рекурсивных) запросов на владение из одного и того же программного потока. Такой мьютекс выполняет меньше работы и функционирует быстрее.
Таблица 10.37. Функции для работы с объектами быстрых мьютексов
Что необходимо сделать | Используемый вызов |
Создать быстрый мьютекс | ExInitializeFastMutex |
Сделать запрос на владение | ExAcquireFastMutex ExAcquireFastMutexUnsafe ExTryToAcquireFastMutex |
Освободить объект |
ExReleaseFastMutex ExReleaseFastMutexUnsafe |
Объект быстрого мьютекса описывается типом FAST_MUTEX (см. например, заголовочный файл DDK wdm.h) и используется для синхронизации доступа к одному или нескольким элементам данных. Любой код, задумавший воспользоваться этими данными, должен сначала сделать запрос на владение соответствующим объектом FAST_MUTEX.
Следует обратить внимание на то, что эти объекты имеют собственные вызовы для выполнения запроса на владение. Функция KeWaitForXxx в данном случае не может быть использована.