Think globally, lock at the smallest scope possible.

Yes, I know that's a rip off of a ThinkGeek shirt (which I own).

Well, this is going to be my second post on this topic (okay, third), but as it managed to rear its head again recently, what better time to blog.  And I'm going to also blog it simply to prove to Doron that I can provide something other than comic relief.

You'll notice a few of the existing UMDF samples have their locking constraint set to WdfDeviceLevel in their Device Initialization routines and some others don't set it at all, which defaults to WdfDeviceLevel.

So, what is the problem with doing it the way some of those samples are?  Well, it does put the widest locking scope on all your objects that the device holds, meaning the device framework acquires a device presentation lock before passing some I/O to their driver callbacks.  This results in serialized calls to that callback for your file and queue operations which is really unnecessary.  There's a really good table in the Windows Driver Foundation book (pg 390) that shows what callbacks are serialized when using the Device Scope level.  And to save some of you looking it up, I'll tell you now that yes, OnDeviceIoControl, OnRead, and OnWrite will get serialized if you set the locking constraint to Device Level.

So unless your driver really requires a synchronization scope that wide, initialize that constraint to None;

 HRESULT
CVDevDevice::Initialize ( 
                         __in IWDFDriver           * FxDriver,
                         __in IWDFDeviceInitialize * FxDeviceInit)
{
    IWDFDevice * fxDevice = NULL;

    HRESULT hr = S_OK;

    FxDeviceInit->SetLockingConstraint (None);

    {
        IUnknown * unknown = this->QueryIUnknown ();

        hr = FxDriver->CreateDevice (FxDeviceInit, unknown, &fxDevice);

        unknown->Release ();
    }

    if (SUCCEEDED (hr)) 
    {
        m_FxDevice = fxDevice;
        fxDevice->Release();
    }

    return hr;
}

The primary differences here between KMDF and UMDF are UMDF doesn't set an execution level, so the likely hood of you bug checking by screwing this up is greatly reduced. :)

 

Edit: For those on RSS, sorry about the embedded style sheet nonsense, I keep forgetting to clear that tick box

*Currently playing - King's X Silent Wind