[ofw] [RFC] [PATCH 1/2] work_queue: new abstraction for queuing work
Fab Tillier
ftillier at windows.microsoft.com
Thu May 21 14:14:17 PDT 2009
>> From the CM callback, you know that the EP is still valid and you can
>> check to see if you have a disconnect request queued. If so, you can
>> remove it from the queue (so it can't be cancelled), and queue the work
>> item using the request as context. From the work item callback,
>> reference the EP and QP (since they now could have been destroyed)
>> based on the IOCTL parameters (just like you did when you first
>> received the IRP), and assuming they're valid, move the QP. You
>> actually might not need to reference the EP, just the QP might do.
>
> This is what the code does. I just didn't realize that I could store
> additional context in the IRP.
I know you can with the IRP, I don't know though if the WDF framework reserves those fields (Tail.Overlay.DriverContext array).
>> No, you could have a pool of work items that you would pull from when
>> you get the CM callback and need to queue it. If the pool is empty,
>> you could allocate new work items dynamically since that is valid
>> operation at DISPATCH.
>
> The work queue abstraction is the pool of work items. I just don't
> allow the pool to grow. And since IO_WORKITEMs are opaque, maintaining
> them in a pool requires additional structures around them. You can't
> just have calls like:
>
> IO_WORKITEM *PoolGet();
> PoolPut(IO_WORKITEM *);
Complib already has what you need: Quick pool.
void* wi_pool_ctor(
void* p_obj,
void* context,
cl_pool_item_t** const pp_item )
{
cl_pool_obj_t* p_new_obj = (cl_pool_obj_t*)p_obj;
p_new_obj->object = IoAllocateWorkItem( (DEVICE_OBJECT*)context );
if( p_new_obj->object == NULL )
{
ExFreePool( p_new_obj );
return CL_ERROR;
}
*pp_item = *p_new_obj->item;
return CL_SUCCESS;
}
void wi_pool_dtor(
void* const cl_pool_item_t* p_item,
void* context )
{
IoFreeWorkItem( ((cl_pool_obj_t*)p_item)->object );
}
cl_qpool_init(
&wi_pool,
WI_POOL_MIN,
WI_POOL_MAX,
WI_POOL_GROW,
sizeof(cl_pool_obj_t),
wi_pool_ctor,
wi_pool_dtor,
pDevObj );
The you can use cl_qpool_get/put with the appropriate cast.
-Fab
More information about the ofw
mailing list