Hi folks,
Just seen an interesting (but somewhat plausibly correct) scenario with WDF.
-
I have some state in my driver which is system global. Since any
device created in my driver can plausibly use it, I use
WdfObjectReference / WdfObjectDereference between some of my internal
objects, the WDF device objects and the WDF driver object.
-
What I’m seeing is that in the case of a failed device add and enable
(D0 power transition failed due to an unrelated issue), I get all the
various cleanup callbacks for that device, but I don’t necessarily get
the destroy callbacks.
-
So what happens is that a few residual bits of state seem to stay
around or at least, not all the destroy callbacks are called.
Is this behaviour by design?
MH.
Cleanup() is called when the object is being rundown, Destroy() is called when the last reference count is removed and goes to zero. ?The object has a biased count of one when created and we decrement the count after cleanup(). If there are no explicit references by the client driver, destroy() will follow immediately. Since you have explicit references, Destroy() will not be called until those references are released.
The pattern here is that you release these (perhaps circular) references in cleanup() so that destroy() can occur. Also, all activity using those references should be stopped in the cleanup() routine so that you can safely release the references. You can leverage the object hierarchy to stop activity. For instance, let’s say that your timer has an explicity reference on object A. Make the timer a child of your device and the timer will have stopped by the time the device’s cleanup() is called so you can safely release the reference in the device’s cleanup routine (this is a bit of a stretch, you can easily do the same thing in the timer’s cleanup() b/c we guarantee the timer is rundown by then as well).
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Martin Harvey
Sent: Tuesday, August 21, 2007 9:22 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WDF cleanup/destroy subtlety.
Hi folks,
Just seen an interesting (but somewhat plausibly correct) scenario with WDF.
-
I have some state in my driver which is system global. Since any
device created in my driver can plausibly use it, I use
WdfObjectReference / WdfObjectDereference between some of my internal
objects, the WDF device objects and the WDF driver object.
-
What I’m seeing is that in the case of a failed device add and enable
(D0 power transition failed due to an unrelated issue), I get all the
various cleanup callbacks for that device, but I don’t necessarily get
the destroy callbacks.
-
So what happens is that a few residual bits of state seem to stay
around or at least, not all the destroy callbacks are called.
Is this behaviour by design?
MH.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
Do you release the references you take on the driver object? The destroy callback isn’t invoked until the reference count drops to zero. If you’ve manually inflated it then you should drop it back down in your various cleanup callbacks and/or failure paths.
-p
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Martin Harvey
Sent: Tuesday, August 21, 2007 9:22 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WDF cleanup/destroy subtlety.
Hi folks,
Just seen an interesting (but somewhat plausibly correct) scenario with WDF.
-
I have some state in my driver which is system global. Since any
device created in my driver can plausibly use it, I use
WdfObjectReference / WdfObjectDereference between some of my internal
objects, the WDF device objects and the WDF driver object.
-
What I’m seeing is that in the case of a failed device add and enable
(D0 power transition failed due to an unrelated issue), I get all the
various cleanup callbacks for that device, but I don’t necessarily get
the destroy callbacks.
-
So what happens is that a few residual bits of state seem to stay
around or at least, not all the destroy callbacks are called.
Is this behaviour by design?
MH.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
Martin Harvey wrote:
- So what happens is that a few residual bits of state seem to stay
around or at least, not all the destroy callbacks are called.
*Big sigh*.
My RefCount error, but worth mentioning for the list, because it’s not
entirely obvious, and is a bit of an edge case concerning PDO creation:
If you do:
WdfObjectReference(some object);
WdfChildListAddOrUpdateChildDescriptionAsPresent
if ! SUCCESS
WdfObjectDereference …
Where for the new device:
pAttrs->EvtCleanupCallback = EvtPdoCleanup;
And EvtPdoCleanup
WdfObjectDereference(some object);
This means when you do:
WdfChildListUpdateChildDescriptionAsMissing,
then you need to do:
if (status == STATUS_NO_SUCH_DEVICE) {
status = STATUS_SUCCESS;
/* Ahhh… child cleanup function is not going to be called, hence,
we need to decrement our reference count manually */
WdfObjectDereference(some object);
}
Makes perfect sense when you see it …
MH.