c++multithreadingkernellockingndis

Using unique locks while in DPC


Currently working on a light weight filter in the NDIS stack. I'm trying to inject a packet which set in a global variable as an NBL. During receive NBL, if an injected NBL is pending, than a lock is taken by the thread before picking the injected NBL up to process it. Originally I was looking at using a spin lock or FAST_MUTEX. But according to the documentation for FAST_MUTEX, any other threads attempting to take the lock will wait for the lock to release before continuing.

The problem is, that receive NBL is running in DPC mode. This would cause a DPC running thread to pause and wait for the lock to release. Additionally, I'd like to be able to assert ownership of a thread's ownership over a lock.

My question is, does windows kernel support unique mutex locks in the kernel, can these locks be taken in DPC mode and how expensive is assertion of ownership in the lock. I'm fairly new to C++ so forgive any syntax errors.

I attempted to define a mutex in the LWF object

// Header file

#pragma once
#include <mutex.h>

class LWFobject
{
public:
  LWFobject()
  std::mutex ExampleMutex;
  std::unique_lock ExampleLock;
}

//=============================================
// CPP file
#include "LWFobject.h"

LWFobject::LWFObject()
{
  ExmapleMutex = CreateMutex( 
        NULL,
        FALSE,    
        NULL); 
  ExampleLock(ExampleMutex, std::defer_lock);
}

Is the use of unique_locks supported in the kernel? When I attempt to compile it, it throws hundreds of compilation errors when attempting to use mutex.h. I'd like to use try_lock and owns_lock.


Solution

  • You can't use standard ISO C++ synchronization mechanisms while inside a Windows kernel.

    A Windows kernel is a whole other world in itself, and requires you to live by its rules (which are vast - see for example these two 700-page books: 1, 2).

    Processing inside a Windows kernel is largely asynchronous and event-based; you handle events and schedule deferred calls or use other synchronization techniques for work that needs to be done later.

    Having said that, it is possible to have a mutex in the traditional sense inside a Windows driver. It's called a Fast Mutex and requires raising IRQL to APC_LEVEL. Then you can use calls like ExAcquireFastMutex, ExTryToAcquireFastMutex and ExReleaseFastMutex to lock/try-lock/release it.