Skip to content
Raymond Chen edited this page Jan 7, 2021 · 2 revisions

The kernel_spin_lock class is defined in wil/resource.h as part of the RAII resource wrappers library. It manages a KSPIN_LOCK exposing appropriate locking methods:

// The constructor initializes the spin lock using KeInitializeSpinLock.
wil::kernel_spin_lock spinLock1;
wil::kernel_spin_lock spinLock2;

// Calls KeAcquireSpinLock. The RAII object returned calls KeReleaseSpinLock
// when it goes out of scope.
auto lockGuard1 = spinLock1.acquire();

// Calls KeAcquireSpinLockAtDpcLevel. The RAII object returned calls
// KeReleaseSpinLockFromDpcLevel when it goes out of scope.
{
    auto lockGuard2 = spinLock2.acquire_at_dpc();
}

// Initialize later.
wil::kspin_lock_guard lockGuard2;

lockGuard2 = spinLock2.acquire();

// Explicit lock release using .reset().
lockGuard2.reset();

The RAII lock guard types returned by these methods are built using unique_any and hence support all the associated functionality, such as default/empty construction, reassignment, explicit reset/release, etc.

Though the need should be rare, if you have a raw KSPIN_LOCK not managed by the WIL class, you can use the following functions in the wil namespace to obtain the same RAII lock guard objects returned by the methods on the class:

// Naturally, the burden is on the user to initialize the KSPIN_LOCK.
KSPIN_LOCK spinLock1;
KeInitializeSpinLock(&spinLock1);
KSPIN_LOCK spinLock2;
KeInitializeSpinLock(&spinLock2);

auto lockGuard1 = wil::acquire_kspin_lock(&spinLock1);
auto lockGuard2 = wil::acquire_kspin_lock_at_dpc(&spinLock2);

Gotchas

Lock guard object

There are some gotchas in the use of the lock guard object returned by the acquire() method and the acquire_kspin_lock_xxx functions. See Lock guard object for details.