- Use a work item for each specific task: start, stop, close

- Should fix bug 4365

svn path=/trunk/; revision=40496
This commit is contained in:
Johannes Anderwald 2009-04-14 07:21:05 +00:00
parent 4efcc91b49
commit 391fa4acd9
7 changed files with 121 additions and 60 deletions

View file

@ -91,7 +91,7 @@ PcAddAdapterDevice(
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDEVICE_OBJECT fdo = NULL;
PDEVICE_OBJECT PrevDeviceObject;
PPCLASS_DEVICE_EXTENSION portcls_ext;
PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;
DPRINT1("PcAddAdapterDevice called\n");
@ -138,8 +138,8 @@ PcAddAdapterDevice(
if (!portcls_ext->CreateItems)
{
/* not enough resources */
IoDeleteDevice(fdo);
return STATUS_INSUFFICIENT_RESOURCES;
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
/* store the physical device object */
@ -157,32 +157,41 @@ PcAddAdapterDevice(
fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
/* allocate work item */
portcls_ext->WorkItem = IoAllocateWorkItem(fdo);
portcls_ext->CloseWorkItem = IoAllocateWorkItem(fdo);
if (!portcls_ext->WorkItem)
if (!portcls_ext->CloseWorkItem)
{
/* not enough resources */
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
/* delete created fdo */
IoDeleteDevice(fdo);
/* return error code */
return STATUS_INSUFFICIENT_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 */
if (!NT_SUCCESS(status))
{
/* free previously allocated create items */
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
/* free allocated work item */
IoFreeWorkItem(portcls_ext->WorkItem);
/* delete created fdo */
IoDeleteDevice(fdo);
/* return error code */
return status;
goto cleanup;
}
/* attach device to device stack */
@ -196,16 +205,52 @@ PcAddAdapterDevice(
}
else
{
/* free the device header */
KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
/* free previously allocated create items */
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
/* free allocated work item */
IoFreeWorkItem(portcls_ext->WorkItem);
/* return error code */
status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
return status;
cleanup:
if (portcls_ext)
{
if (portcls_ext->KsDeviceHeader)
{
/* free the device header */
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 */
FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
}
}
if (fdo)
{
/* delete created fdo */
IoDeleteDevice(fdo);
/* return error code */
return STATUS_UNSUCCESSFUL;
}
return status;

View file

@ -405,6 +405,9 @@ IDmaChannelSlave_fnStop(
This->DmaStarted = FALSE;
IoFreeMdl(This->Mdl);
This->Mdl = NULL;
return STATUS_SUCCESS;
}

View file

@ -113,6 +113,7 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
{
/* release existing instance */
ASSERT(0);
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
}

View file

@ -199,12 +199,18 @@ StopStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context;
DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
/* 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;
DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
}
VOID
@ -219,15 +225,24 @@ StopStreamRoutine(
PPCLASS_DEVICE_EXTENSION DeviceExtension;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
/* Has the audio stream resumed? */
if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue))
return;
/* Has the audio stream already stopped */
if (This->State == KSSTATE_STOP)
return;
/* Get device object */
DeviceObject = GetDeviceObject(This->Port);
/* Get device extension */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* queue the work item */
IoQueueWorkItem(DeviceExtension->WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This);
IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This);
}
static
@ -696,23 +711,18 @@ IPortPinWaveCyclic_fnClose(
if (This->Stream)
{
if (Irp)
{
This->CloseIrp = Irp;
IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
}
/* Get device extension */
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* defer work item */
IoQueueWorkItem(DeviceExtension->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This);
if (Irp)
{
/* The WaveCyclic filter passes close request with NULL / IRP */
return STATUS_PENDING;
}
This->CloseIrp = Irp;
IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
/* defer work item */
IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This);
/* Return result */
return STATUS_PENDING;
}
if (Irp)

View file

@ -602,8 +602,7 @@ PcCreateItemDispatch(
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
IoQueueWorkItem(DeviceExt->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING;
}
}

View file

@ -156,7 +156,10 @@ typedef struct
ULONG MaxSubDevices;
KSOBJECT_CREATE_ITEM * CreateItems;
PIO_WORKITEM WorkItem;
PIO_WORKITEM StartWorkItem;
PIO_WORKITEM StopWorkItem;
PIO_WORKITEM CloseWorkItem;
IResourceList* resources;
LIST_ENTRY SubDeviceList;
LIST_ENTRY PhysicalConnectionList;

View file

@ -29,7 +29,7 @@ typedef struct CResourceList
*/
NTSTATUS
STDMETHODCALLTYPE
NTAPI
IResourceList_fnQueryInterface(
IResourceList* iface,
IN REFIID refiid,
@ -56,7 +56,7 @@ IResourceList_fnQueryInterface(
}
ULONG
STDMETHODCALLTYPE
NTAPI
IResourceList_fnAddRef(
IResourceList* iface)
{
@ -66,7 +66,7 @@ IResourceList_fnAddRef(
}
ULONG
STDMETHODCALLTYPE
NTAPI
IResourceList_fnRelease(
IResourceList* iface)
{
@ -93,7 +93,7 @@ IResourceList_fnRelease(
*/
ULONG
STDMETHODCALLTYPE
NTAPI
IResourceList_fnNumberOfEntries(IResourceList* iface)
{
IResourceListImpl * This = (IResourceListImpl*)iface;
@ -102,7 +102,7 @@ IResourceList_fnNumberOfEntries(IResourceList* iface)
}
ULONG
STDMETHODCALLTYPE
NTAPI
IResourceList_fnNumberOfEntriesOfType(
IResourceList* iface,
IN CM_RESOURCE_TYPE Type)
@ -129,7 +129,7 @@ IResourceList_fnNumberOfEntriesOfType(
}
PCM_PARTIAL_RESOURCE_DESCRIPTOR
STDMETHODCALLTYPE
NTAPI
IResourceList_fnFindTranslatedEntry(
IResourceList* iface,
IN CM_RESOURCE_TYPE Type,
@ -158,7 +158,7 @@ IResourceList_fnFindTranslatedEntry(
}
PCM_PARTIAL_RESOURCE_DESCRIPTOR
STDMETHODCALLTYPE
NTAPI
IResourceList_fnFindUntranslatedEntry(
IResourceList* iface,
IN CM_RESOURCE_TYPE Type,
@ -186,7 +186,7 @@ IResourceList_fnFindUntranslatedEntry(
}
NTSTATUS
STDMETHODCALLTYPE
NTAPI
IResourceList_fnAddEntry(
IResourceList* iface,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated,
@ -242,7 +242,7 @@ IResourceList_fnAddEntry(
}
NTSTATUS
STDMETHODCALLTYPE
NTAPI
IResourceList_fnAddEntryFromParent(
IResourceList* iface,
IN IResourceList* Parent,
@ -281,7 +281,7 @@ IResourceList_fnAddEntryFromParent(
}
PCM_RESOURCE_LIST
STDMETHODCALLTYPE
NTAPI
IResourceList_fnTranslatedList(
IResourceList* iface)
{
@ -291,7 +291,7 @@ IResourceList_fnTranslatedList(
}
PCM_RESOURCE_LIST
STDMETHODCALLTYPE
NTAPI
IResourceList_fnUntranslatedList(
IResourceList* iface)
{
@ -325,7 +325,9 @@ static const IResourceListVtbl vt_ResourceListVtbl =
/*
Factory for creating a resource list
*/
PORTCLASSAPI NTSTATUS NTAPI
PORTCLASSAPI
NTSTATUS
NTAPI
PcNewResourceList(
OUT PRESOURCELIST* OutResourceList,
IN PUNKNOWN OuterUnknown OPTIONAL,
@ -339,8 +341,6 @@ PcNewResourceList(
/* TODO: Validate parameters */
DPRINT("PcNewResourceList\n");
NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS);
if (!NewList)