- Allocate a work item for each specific request (start / stop / close) and free allocated work items

svn path=/trunk/; revision=40645
This commit is contained in:
Johannes Anderwald 2009-04-22 10:17:40 +00:00
parent 7699f9cb05
commit 7a75a5802f
6 changed files with 121 additions and 95 deletions

View file

@ -156,36 +156,6 @@ PcAddAdapterDevice(
/* clear initializing flag */ /* clear initializing flag */
fdo->Flags &= ~ DO_DEVICE_INITIALIZING; fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
/* allocate work item */
portcls_ext->CloseWorkItem = IoAllocateWorkItem(fdo);
if (!portcls_ext->CloseWorkItem)
{
/* not enough resources */
goto cleanup;
status = STATUS_INSUFFICIENT_RESOURCES;
}
/* allocate work item */
portcls_ext->StartWorkItem = IoAllocateWorkItem(fdo);
if (!portcls_ext->StartWorkItem)
{
/* not enough resources */
goto cleanup;
status = STATUS_INSUFFICIENT_RESOURCES;
}
/* allocate work item */
portcls_ext->StopWorkItem = IoAllocateWorkItem(fdo);
if (!portcls_ext->StopWorkItem)
{
/* not enough resources */
goto cleanup;
status = STATUS_INSUFFICIENT_RESOURCES;
}
/* allocate the device header */ /* allocate the device header */
status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems); status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
/* did we succeed */ /* did we succeed */
@ -222,24 +192,6 @@ cleanup:
KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
} }
if (portcls_ext->CloseWorkItem)
{
/* free allocated work item */
IoFreeWorkItem(portcls_ext->CloseWorkItem);
}
if (portcls_ext->StartWorkItem)
{
/* free allocated work item */
IoFreeWorkItem(portcls_ext->StartWorkItem);
}
if (portcls_ext->StopWorkItem)
{
/* free allocated work item */
IoFreeWorkItem(portcls_ext->StopWorkItem);
}
if (portcls_ext->CreateItems) if (portcls_ext->CreateItems)
{ {
/* free previously allocated create items */ /* free previously allocated create items */

View file

@ -116,11 +116,11 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) if (This->Pins[ConnectDetails->PinId] &&
(This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount == This->Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount))
{ {
/* release existing instance */ /* release existing instance */
ASSERT(0); return STATUS_UNSUCCESSFUL;
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
} }
/* now create the pin */ /* now create the pin */

View file

@ -38,7 +38,6 @@ typedef struct
ULONG DelayedRequestInProgress; ULONG DelayedRequestInProgress;
ULONG FrameSize; ULONG FrameSize;
BOOL Capture; BOOL Capture;
PIRP CloseIrp;
}IPortPinWaveCyclicImpl; }IPortPinWaveCyclicImpl;
@ -199,18 +198,20 @@ StopStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context) IN PVOID Context)
{ {
PPCLASS_DEVICE_EXTENSION DeviceExtension; IPortPinWaveCyclicImpl * This;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context; PSTOPSTREAM_CONTEXT Ctx = (PSTOPSTREAM_CONTEXT)Context;
This = (IPortPinWaveCyclicImpl*)Ctx->Pin;
/* Set the state to stop */ /* Set the state to stop */
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
/* Set internal state to stop */ /* Set internal state to stop */
This->State = KSSTATE_STOP; This->State = KSSTATE_STOP;
/* Get device extension */ IoFreeWorkItem(Ctx->WorkItem);
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FreeItem(Ctx, TAG_PORTCLASS);
DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql()); DPRINT1("Stopping %p %u Irql %u\n", This, This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
} }
VOID VOID
@ -222,8 +223,9 @@ StopStreamRoutine(
IN PVOID SystemArgument2) IN PVOID SystemArgument2)
{ {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PPCLASS_DEVICE_EXTENSION DeviceExtension;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
PIO_WORKITEM WorkItem;
PSTOPSTREAM_CONTEXT Context;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
@ -238,11 +240,26 @@ StopStreamRoutine(
/* Get device object */ /* Get device object */
DeviceObject = GetDeviceObject(This->Port); DeviceObject = GetDeviceObject(This->Port);
/* Get device extension */ /* allocate stop context */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; Context = AllocateItem(NonPagedPool, sizeof(STOPSTREAM_CONTEXT), TAG_PORTCLASS);
if (!Context)
return;
/* allocate work item */
WorkItem = IoAllocateWorkItem(DeviceObject);
if (!WorkItem)
{
ExFreePool(Context);
return;
}
Context->Pin = (PVOID)This;
Context->WorkItem = WorkItem;
/* queue the work item */ /* queue the work item */
IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); IoQueueWorkItem(WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
} }
static static
@ -642,8 +659,10 @@ CloseStreamRoutine(
NTSTATUS Status; NTSTATUS Status;
ISubdevice *ISubDevice; ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor; PSUBDEVICE_DESCRIPTOR Descriptor;
IPortPinWaveCyclicImpl * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context; This = (IPortPinWaveCyclicImpl*)Ctx->Pin;
if (This->Stream) if (This->Stream)
{ {
@ -680,17 +699,21 @@ CloseStreamRoutine(
This->IrpQueue->lpVtbl->Release(This->IrpQueue); This->IrpQueue->lpVtbl->Release(This->IrpQueue);
} }
/* complete the irp */
Ctx->Irp->IoStatus.Information = 0;
Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
/* free the work item */
IoFreeWorkItem(Ctx->WorkItem);
/* free work item ctx */
FreeItem(Ctx, TAG_PORTCLASS);
if (This->Stream) if (This->Stream)
{ {
Stream = This->Stream; Stream = This->Stream;
This->Stream = NULL; This->Stream = NULL;
if (This->CloseIrp)
{
This->CloseIrp->IoStatus.Information = 0;
This->CloseIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(This->CloseIrp, IO_NO_INCREMENT);
}
DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
Stream->lpVtbl->Release(Stream); Stream->lpVtbl->Release(Stream);
/* this line is never reached */ /* this line is never reached */
@ -707,32 +730,54 @@ IPortPinWaveCyclic_fnClose(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PPCLASS_DEVICE_EXTENSION DeviceExtension; PCLOSESTREAM_CONTEXT Ctx;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
if (This->Stream) if (This->Stream)
{ {
/* Get device extension */ Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (!Ctx)
{
DPRINT1("Failed to allocate stream context\n");
goto cleanup;
}
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem)
{
DPRINT1("Failed to allocate work item\n");
goto cleanup;
}
Ctx->Irp = Irp;
Ctx->Pin = (PVOID)This;
This->CloseIrp = Irp;
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING; Irp->IoStatus.Status = STATUS_PENDING;
/* defer work item */ /* defer work item */
IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This); IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
/* Return result */ /* Return result */
return STATUS_PENDING; return STATUS_PENDING;
} }
if (Irp)
{
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
cleanup:
if (Ctx)
FreeItem(Ctx, TAG_PORTCLASS);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
} }
/* /*
@ -971,9 +1016,9 @@ IPortPinWaveCyclic_fnInit(
DPRINT1("Failed to add pin to service group\n"); DPRINT1("Failed to add pin to service group\n");
return Status; return Status;
} }
This->ServiceGroup->lpVtbl->AddRef(This->ServiceGroup); //This->ServiceGroup->lpVtbl->AddRef(This->ServiceGroup);
This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup); This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
This->DmaChannel->lpVtbl->AddRef(This->DmaChannel); //This->DmaChannel->lpVtbl->AddRef(This->DmaChannel);
This->State = KSSTATE_STOP; This->State = KSSTATE_STOP;

View file

@ -29,7 +29,7 @@ typedef struct
{ {
PIRP Irp; PIRP Irp;
IIrpTarget *Filter; IIrpTarget *Filter;
PIO_WORKITEM WorkItem;
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; }PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
static GUID InterfaceGuids[2] = static GUID InterfaceGuids[2] =
@ -459,7 +459,7 @@ CreatePinWorkerRoutine(
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
DPRINT("CreatePinWorkerRoutine called\n"); DPRINT("CreatePinWorkerRoutine called\n");
/* create the pin */
Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter, Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter,
&Pin, &Pin,
NULL, NULL,
@ -479,10 +479,15 @@ CreatePinWorkerRoutine(
} }
DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp); DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp);
/* save status in irp */
WorkerContext->Irp->IoStatus.Status = Status; WorkerContext->Irp->IoStatus.Status = Status;
WorkerContext->Irp->IoStatus.Information = 0; WorkerContext->Irp->IoStatus.Information = 0;
/* complete the request */
IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
ExFreePool(WorkerContext); /* free allocated work item */
IoFreeWorkItem(WorkerContext->WorkItem);
/* free context */
FreeItem(WorkerContext, TAG_PORTCLASS);
} }
@ -590,11 +595,24 @@ PcCreateItemDispatch(
Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
if (!Context) if (!Context)
{ {
DPRINT("Failed to allocate worker context\n");
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
/* allocate work item */
Context->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Context->WorkItem)
{
DPRINT("Failed to allocate workitem\n");
FreeItem(Context, TAG_PORTCLASS);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
Context->Filter = Filter; Context->Filter = Filter;
Context->Irp = Irp; Context->Irp = Irp;
@ -602,7 +620,7 @@ PcCreateItemDispatch(
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING; Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING; return STATUS_PENDING;
} }
} }

View file

@ -169,10 +169,6 @@ typedef struct
ULONG MaxSubDevices; ULONG MaxSubDevices;
KSOBJECT_CREATE_ITEM * CreateItems; KSOBJECT_CREATE_ITEM * CreateItems;
PIO_WORKITEM StartWorkItem;
PIO_WORKITEM StopWorkItem;
PIO_WORKITEM CloseWorkItem;
IResourceList* resources; IResourceList* resources;
LIST_ENTRY SubDeviceList; LIST_ENTRY SubDeviceList;
LIST_ENTRY PhysicalConnectionList; LIST_ENTRY PhysicalConnectionList;
@ -186,6 +182,19 @@ typedef struct
PIRP Irp; PIRP Irp;
}CONTEXT_WRITE, *PCONTEXT_WRITE; }CONTEXT_WRITE, *PCONTEXT_WRITE;
typedef struct
{
PVOID Pin;
PIO_WORKITEM WorkItem;
}STOPSTREAM_CONTEXT, *PSTOPSTREAM_CONTEXT;
typedef struct
{
PVOID Pin;
PIO_WORKITEM WorkItem;
PIRP Irp;
}CLOSESTREAM_CONTEXT, *PCLOSESTREAM_CONTEXT;
NTSTATUS NTSTATUS
NTAPI NTAPI
PcDmaMasterDescription( PcDmaMasterDescription(

View file

@ -427,10 +427,12 @@ PcPropertyHandler(
DPRINT("Calling property handler %p\n", PropertyHandler); DPRINT("Calling property handler %p\n", PropertyHandler);
Status = PropertyHandler(Irp, Property, Irp->UserBuffer); Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
} }
else
{
RtlStringFromGUID(&Property->Set, &GuidString); RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString); RtlFreeUnicodeString(&GuidString);
}
/* the information member is set by the handler */ /* the information member is set by the handler */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;