mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
- 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:
parent
7699f9cb05
commit
7a75a5802f
6 changed files with 121 additions and 95 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue