Hi,
I’m trying to use the work item mechanism on *Windows XP*, but have been unsuccessfull so far. I’m using the general idea from this place: http://www.microsoft.com/whdc/driver/tips/workitem.mspx
Here is my code snippet for queueing work item:
IndicateWorkItemContext *iwic = MEMALLOC_S(context->handles.adapter, IndicateWorkItemContext);
if (iwic != NULL)
{
/* setup the context */
iwic->adapter = context->handles.adapter;
iwic->packet = packet;
/* queue packet for indication and check if we need to queue work item */
if (NdisInterlockedInsertTailList(&_wi.queue, &iwic->contexts, &_wi.lock) == NULL)
{
DBGPRINT(DL_LOG8, " queueing work item %p, context %p", iwic->item, iwic);
IoQueueWorkItem(_wi.handle, indicateWorkItemRoutine, DelayedWorkQueue, &_wi);
}
[…]
}
and for work item routine:
static VOID indicateWorkItemRoutine(
__in PDEVICE_OBJECT DeviceObject,
__in_opt PVOID Context
)
{
WorkItem *wi = (WorkItem *)Context;
PLIST_ENTRY e = NdisInterlockedRemoveHeadList(&wi->queue, &wi->lock);
/* walk through the context queue */
for (; e != NULL; e = NdisInterlockedRemoveHeadList(&wi->queue, &wi->lock))
{
/* get work item context */
IndicateWorkItemContext *iwic = CONTAINING_RECORD(e, IndicateWorkItemContext, contexts);
/* indicate */
NdisMIndicateReceivePacket(iwic->adapter, &iwic->packet, 1);
/* release work item context memory */
MEMFREE_S(iwic);
}
}
MS documentation states that by the time the work item is executed it’s out of the work items queue, so it could be queued again. Apparently it’s not so (or at least I think it is not) because the checked build of Windows XP asserts in IoQueueWorkItem:
Assertion failed: WorkItem->List.Flink == NULL
*** Source File: d:\xpsp\base\ntos\ex\worker.c, line 523
So the question is if it’s still in the queue (according to the assert)? Maybe there is a bug in the code above I don’t see or the whole concept behind this code is wrong?
Would it be better to allocate new work item on every request and queue it and free it in the work item routine?
Thank you in advance!
Regards,
Igor