Author: janderwald
Date: Wed Apr 22 14:57:28 2009
New Revision: 40646
URL:
http://svn.reactos.org/svn/reactos?rev=40646&view=rev
Log:
- Allocate work item for each filter / pin being opened
- Use ExInterlockedInsertTailList to insert a new audio device to prevent race conditions
when more than one audio device is present
- Free work item in their target worker routine
Modified:
trunk/reactos/drivers/wdm/audio/sysaudio/control.c
trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
trunk/reactos/drivers/wdm/audio/sysaudio/main.c
trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Wed Apr 22 14:57:28
2009
@@ -236,6 +236,8 @@
{
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
ExFreePool(WorkerContext->DispatchContext);
+ IoFreeWorkItem(WorkerContext->WorkItem);
+ ExFreePool(WorkerContext);
return;
}
@@ -252,6 +254,8 @@
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
ExFreePool(WorkerContext->DispatchContext);
ExFreePool(MixerPinConnect);
+ IoFreeWorkItem(WorkerContext->WorkItem);
+ ExFreePool(WorkerContext);
return;
}
@@ -391,8 +395,9 @@
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
+ IoFreeWorkItem(WorkerContext->WorkItem);
+ ExFreePool(WorkerContext);
return;
-
cleanup:
if (RealFileObject)
@@ -410,7 +415,8 @@
ExFreePool(WorkerContext->DispatchContext);
SetIrpIoStatus(WorkerContext->Irp, Status, 0);
-
+ IoFreeWorkItem(WorkerContext->WorkItem);
+ ExFreePool(WorkerContext);
}
NTSTATUS
@@ -722,8 +728,7 @@
KSPIN_CINSTANCES PinInstances;
PPIN_WORKER_CONTEXT WorkerContext;
PDISPATCH_CONTEXT DispatchContext;
-
-
+ PIO_WORKITEM WorkItem;
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -806,10 +811,7 @@
}
}
- ASSERT(DeviceExtension->WorkItem);
- ASSERT(DeviceExtension->WorkerContext);
-
- /* create worker context */
+ /* create dispatch pin context */
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
if (!DispatchContext)
{
@@ -817,11 +819,24 @@
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
- // FIXME
- // mutal exclusion
-
- /* get worker context */
- WorkerContext = (PPIN_WORKER_CONTEXT)DeviceExtension->WorkerContext;
+ /* allocate worker context */
+ WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
+ if (!WorkerContext)
+ {
+ /* no memory */
+ ExFreePool(DispatchContext);
+ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ }
+
+ /* allocate work item */
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (!WorkerContext)
+ {
+ /* no memory */
+ ExFreePool(DispatchContext);
+ ExFreePool(WorkerContext);
+ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ }
/* prepare context */
RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
@@ -841,13 +856,14 @@
WorkerContext->PinConnect = PinConnect;
WorkerContext->AudioClient = ClientInfo;
WorkerContext->DeviceExtension = DeviceExtension;
+ WorkerContext->WorkItem = WorkItem;
DPRINT("Queing Irp %p\n", Irp);
/* queue the work item */
IoMarkIrpPending(Irp);
Irp->IoStatus.Status = STATUS_PENDING;
Irp->IoStatus.Information = 0;
- IoQueueWorkItem(DeviceExtension->WorkItem, CreatePinWorkerRoutine,
DelayedWorkQueue, (PVOID)WorkerContext);
+ IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue,
(PVOID)WorkerContext);
/* mark irp as pending */
return STATUS_PENDING;
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Wed Apr 22 14:57:28
2009
@@ -28,7 +28,10 @@
NTSTATUS Status;
ULONG BytesReturned;
PSYSAUDIODEVEXT DeviceExtension;
- PKSAUDIO_DEVICE_ENTRY DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)Context;
+ PKSAUDIO_DEVICE_ENTRY DeviceEntry;
+ PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context;
+
+ DeviceEntry = Ctx->DeviceEntry;
DPRINT("Querying filter...\n");
@@ -42,21 +45,13 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to query number of pins Status %x\n", Status);
- ObDereferenceObject(DeviceEntry->FileObject);
- ZwClose(DeviceEntry->Handle);
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return;
+ goto cleanup;
}
if (!Count)
{
DPRINT1("Filter has no pins!\n");
- ObDereferenceObject(DeviceEntry->FileObject);
- ZwClose(DeviceEntry->Handle);
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return;
+ goto cleanup;
}
/* allocate pin array */
@@ -65,11 +60,7 @@
{
/* no memory */
DPRINT1("Failed to allocate memory Block %x\n", Count *
sizeof(PIN_INFO));
- ObDereferenceObject(DeviceEntry->FileObject);
- ZwClose(DeviceEntry->Handle);
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return;
+ goto cleanup;
}
/* clear array */
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
@@ -114,12 +105,27 @@
}
DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n",
DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin,
DeviceEntry->NumWaveOutPin);
-
+ /* fetch device extension */
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-
- InsertTailList(&DeviceExtension->KsAudioDeviceList,
&DeviceEntry->Entry);
- DeviceExtension->NumberOfKsAudioDevices++;
-
+ /* insert new audio device */
+ ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList,
&DeviceEntry->Entry, &DeviceExtension->Lock);
+ /* increment audio device count */
+ InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
+
+ /* free work item */
+ IoFreeWorkItem(Ctx->WorkItem);
+ /* free work item context */
+ ExFreePool(Ctx);
+ return;
+
+cleanup:
+
+ ObDereferenceObject(DeviceEntry->FileObject);
+ ZwClose(DeviceEntry->Handle);
+ ExFreePool(DeviceEntry->DeviceName.Buffer);
+ ExFreePool(DeviceEntry);
+ IoFreeWorkItem(Ctx->WorkItem);
+ ExFreePool(Ctx);
}
NTSTATUS
@@ -177,7 +183,9 @@
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
NTSTATUS Status = STATUS_SUCCESS;
PSYSAUDIODEVEXT DeviceExtension;
- PKSAUDIO_DEVICE_ENTRY DeviceEntry;
+ PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
+ PIO_WORKITEM WorkItem = NULL;
+ PFILTER_WORKER_CONTEXT Ctx = NULL;
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
@@ -191,48 +199,67 @@
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
if (!DeviceEntry)
{
-
+ /* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
+ /* initialize audio device entry */
RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
+
+ /* allocate filter ctx */
+ Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT));
+ if (!Ctx)
+ {
+ /* no memory */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ /* allocate work item */
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (!WorkItem)
+ {
+ /* no memory */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ /* set device name */
DeviceEntry->DeviceName.Length = 0;
DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length
+ 5 * sizeof(WCHAR);
DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool,
DeviceEntry->DeviceName.MaximumLength);
+
if (!DeviceEntry->DeviceName.Buffer)
{
- ExFreePool(DeviceEntry);
- return STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
}
if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName,
L"\\??\\")))
{
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return STATUS_INSUFFICIENT_RESOURCES;
+ DPRINT1("RtlAppendUnicodeToString failed with %x\n", Status);
+ goto cleanup;
}
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName,
Event->SymbolicLinkName)))
{
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return STATUS_INSUFFICIENT_RESOURCES;
+ DPRINT1("RtlAppendUnicodeStringToString failed with %x\n",
Status);
+ goto cleanup;
}
Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle,
&DeviceEntry->FileObject);
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateFile failed with %x\n", Status);
- ExFreePool(DeviceEntry->DeviceName.Buffer);
- ExFreePool(DeviceEntry);
- return Status;
+ goto cleanup;
}
DPRINT("Successfully opened audio device %u handle %p file object %p device
object %p\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->Handle,
DeviceEntry->FileObject, DeviceEntry->FileObject->DeviceObject);
- //FIXME
- // mutal exclusion
- IoQueueWorkItem(DeviceExtension->WorkItem, FilterPinWorkerRoutine,
DelayedWorkQueue, (PVOID)DeviceEntry);
+ Ctx->DeviceEntry = DeviceEntry;
+ Ctx->WorkItem = WorkItem;
+
+ IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
return Status;
}
else
@@ -241,6 +268,23 @@
UNIMPLEMENTED
return STATUS_SUCCESS;
}
+
+cleanup:
+ if (Ctx)
+ ExFreePool(Ctx);
+
+ if (WorkItem)
+ IoFreeWorkItem(WorkItem);
+
+ if (DeviceEntry)
+ {
+ if (DeviceEntry->DeviceName.Buffer)
+ ExFreePool(DeviceEntry->DeviceName.Buffer);
+
+ ExFreePool(DeviceEntry);
+ }
+
+ return Status;
}
NTSTATUS
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Wed Apr 22 14:57:28 2009
@@ -118,7 +118,7 @@
RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
/* Initialize the mutex */
- KeInitializeMutex(&DeviceExtension->Mutex, 0);
+ KeInitializeSpinLock(&DeviceExtension->Lock);
/* Initialize the ks audio device list */
InitializeListHead(&DeviceExtension->KsAudioDeviceList);
@@ -128,22 +128,6 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
- goto cleanup;
- }
-
- /* allocate work item */
- DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject);
- if (!DeviceExtension->WorkItem)
- {
- DPRINT1("Failed to allocate work item\n");
- goto cleanup;
- }
-
- /* allocate work item context */
- DeviceExtension->WorkerContext = ExAllocatePool(NonPagedPool,
sizeof(PIN_WORKER_CONTEXT));
- if (!DeviceExtension->WorkerContext)
- {
- DPRINT1("Failed to allocate work item context\n");
goto cleanup;
}
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Wed Apr 22 14:57:28
2009
@@ -70,13 +70,10 @@
LIST_ENTRY KsAudioDeviceList; // audio device list
PVOID KsAudioNotificationEntry; // ks audio notification hook
PVOID EchoCancelNotificationEntry; // ks echo cancel notification
hook
- KMUTEX Mutex; // audio device list mutex
+ KSPIN_LOCK Lock; // audio device list mutex
PFILE_OBJECT KMixerFileObject; // mixer file object
HANDLE KMixerHandle; // mixer file handle
-
- PIO_WORKITEM WorkItem; // work item for pin creation
- PVOID WorkerContext; // work item context
}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
@@ -113,7 +110,15 @@
PSYSAUDIO_CLIENT AudioClient;
PSYSAUDIODEVEXT DeviceExtension;
PKSDATAFORMAT_WAVEFORMATEX MixerFormat;
+ PIO_WORKITEM WorkItem;
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
+
+typedef struct
+{
+ PIO_WORKITEM WorkItem;
+ PKSAUDIO_DEVICE_ENTRY DeviceEntry;
+}FILTER_WORKER_CONTEXT, *PFILTER_WORKER_CONTEXT;
+
NTSTATUS
SysAudioAllocateDeviceHeader(