Would someone be kind enough to explain the WHY of sample code that does the following:
KeEnterCriticalRegion()
ExAcquireFastMutex()
…
deep thoughts here
…
ExReleaseFastMutex()
KeLeaveCriticalRegion();
I’ve got a snippet of the OSR article pasted in below and I just don’t understand why one of these guys (Mutex or Critical Region) is not sufficient? I’d sure like to understand why both are necessary. Maybe you could throw in an example of what could happen if one or the other is not there.
TIA
Larry.
from the article:
Asynchronous Procedure Calls in Windows NT
Content provided by OSR Open Systems Resources, Inc.
… To alleviate this situation, a typical Windows NT file system disables kernel mode APC delivery by calling KeEnterCriticalRegion(…) (albeit under the name FsRtlEnterFileSystem(…), which in current versions of Windows NT is defined to be KeEnterCriticalRegion(…).) This disables the delivery of kernel mode APCs, although it allows the I/O Manager’s special kernel mode APCs to be delivered. These APCs are safe because they do not re-enter the file system and hence do not introduce any risk of deadlock.
Another way that APC delivery can be disabled is to raise the IRQL of the system to APC_LEVEL. This disables the delivery of all APCs, of any type. For example, the Windows NT Memory Manager issues I/O operations at APC_LEVEL under certain circumstances. This ensures that any APCs, especially I/O completion APCs, are not delivered while it is starting a new paging I/O operation.
Some of the synchronization primitives in Windows NT raise the IRQL of the running system to APC_LEVEL in order to ensure that code cannot re-enter for the currently running thread. The notable case here is the fast mutex operations. ExAcquireFastMutex(…) raises the IRQL of the system to APC_LEVEL, lowering it when the driver calls ExReleaseFastMutex(…). Thus, while a fast mutex is held, all APCs for this thread are not delivered.