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

View file

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

View file

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

View file

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

View file

@ -602,8 +602,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->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING; return STATUS_PENDING;
} }
} }

View file

@ -156,7 +156,10 @@ typedef struct
ULONG MaxSubDevices; ULONG MaxSubDevices;
KSOBJECT_CREATE_ITEM * CreateItems; KSOBJECT_CREATE_ITEM * CreateItems;
PIO_WORKITEM WorkItem; 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;

View file

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