- 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 */
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 */
status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
/* did we succeed */
@ -222,24 +192,6 @@ cleanup:
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)
{
/* free previously allocated create items */

View file

@ -116,11 +116,11 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
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 */
ASSERT(0);
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
return STATUS_UNSUCCESSFUL;
}
/* now create the pin */

View file

@ -38,7 +38,6 @@ typedef struct
ULONG DelayedRequestInProgress;
ULONG FrameSize;
BOOL Capture;
PIRP CloseIrp;
}IPortPinWaveCyclicImpl;
@ -199,18 +198,20 @@ StopStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
IPortPinWaveCyclicImpl * This;
PSTOPSTREAM_CONTEXT Ctx = (PSTOPSTREAM_CONTEXT)Context;
This = (IPortPinWaveCyclicImpl*)Ctx->Pin;
/* Set the state to stop */
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
/* Set internal state to stop */
This->State = KSSTATE_STOP;
/* Get device extension */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoFreeWorkItem(Ctx->WorkItem);
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
@ -222,8 +223,9 @@ StopStreamRoutine(
IN PVOID SystemArgument2)
{
PDEVICE_OBJECT DeviceObject;
PPCLASS_DEVICE_EXTENSION DeviceExtension;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
PIO_WORKITEM WorkItem;
PSTOPSTREAM_CONTEXT Context;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
@ -238,11 +240,26 @@ StopStreamRoutine(
/* Get device object */
DeviceObject = GetDeviceObject(This->Port);
/* Get device extension */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* allocate stop context */
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 */
IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This);
IoQueueWorkItem(WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
}
static
@ -636,14 +653,16 @@ VOID
NTAPI
CloseStreamRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
IN PVOID Context)
{
PMINIPORTWAVECYCLICSTREAM Stream;
NTSTATUS Status;
ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
IPortPinWaveCyclicImpl * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
This = (IPortPinWaveCyclicImpl*)Ctx->Pin;
if (This->Stream)
{
@ -680,17 +699,21 @@ CloseStreamRoutine(
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)
{
Stream = This->Stream;
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());
Stream->lpVtbl->Release(Stream);
/* this line is never reached */
@ -707,32 +730,54 @@ IPortPinWaveCyclic_fnClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
PCLOSESTREAM_CONTEXT Ctx;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
if (This->Stream)
{
/* Get device extension */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
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);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
/* defer work item */
IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This);
IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
/* Return result */
return STATUS_PENDING;
}
if (Irp)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
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");
return Status;
}
This->ServiceGroup->lpVtbl->AddRef(This->ServiceGroup);
//This->ServiceGroup->lpVtbl->AddRef(This->ServiceGroup);
This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
This->DmaChannel->lpVtbl->AddRef(This->DmaChannel);
//This->DmaChannel->lpVtbl->AddRef(This->DmaChannel);
This->State = KSSTATE_STOP;

View file

@ -29,7 +29,7 @@ typedef struct
{
PIRP Irp;
IIrpTarget *Filter;
PIO_WORKITEM WorkItem;
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
static GUID InterfaceGuids[2] =
@ -459,7 +459,7 @@ CreatePinWorkerRoutine(
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
DPRINT("CreatePinWorkerRoutine called\n");
/* create the pin */
Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter,
&Pin,
NULL,
@ -479,10 +479,15 @@ CreatePinWorkerRoutine(
}
DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp);
/* save status in irp */
WorkerContext->Irp->IoStatus.Status = Status;
WorkerContext->Irp->IoStatus.Information = 0;
/* complete the request */
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);
if (!Context)
{
DPRINT("Failed to allocate worker context\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
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->Irp = Irp;
@ -602,7 +620,7 @@ PcCreateItemDispatch(
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING;
}
}

View file

@ -169,10 +169,6 @@ typedef struct
ULONG MaxSubDevices;
KSOBJECT_CREATE_ITEM * CreateItems;
PIO_WORKITEM StartWorkItem;
PIO_WORKITEM StopWorkItem;
PIO_WORKITEM CloseWorkItem;
IResourceList* resources;
LIST_ENTRY SubDeviceList;
LIST_ENTRY PhysicalConnectionList;
@ -186,6 +182,19 @@ typedef struct
PIRP Irp;
}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
NTAPI
PcDmaMasterDescription(

View file

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