hidclass.sys: Make read IRP queue thread safe.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
08a899d433
commit
85082e8bd3
|
@ -1,6 +1,6 @@
|
|||
MODULE = hidclass.sys
|
||||
IMPORTLIB = hidclass
|
||||
IMPORTS = ntoskrnl
|
||||
IMPORTS = hal ntoskrnl
|
||||
DELAYIMPORTS = setupapi hid
|
||||
|
||||
C_SRCS = \
|
||||
|
|
|
@ -126,10 +126,25 @@ error:
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
static IRP *pop_irp_from_queue(BASE_DEVICE_EXTENSION *ext)
|
||||
{
|
||||
LIST_ENTRY *entry;
|
||||
KIRQL old_irql;
|
||||
IRP *irp = NULL;
|
||||
|
||||
KeAcquireSpinLock(&ext->irp_queue_lock, &old_irql);
|
||||
|
||||
entry = RemoveHeadList(&ext->irp_queue);
|
||||
if (entry != &ext->irp_queue)
|
||||
irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry);
|
||||
|
||||
KeReleaseSpinLock(&ext->irp_queue_lock, old_irql);
|
||||
return irp;
|
||||
}
|
||||
|
||||
void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device)
|
||||
{
|
||||
BASE_DEVICE_EXTENSION *ext;
|
||||
LIST_ENTRY *entry;
|
||||
IRP *irp;
|
||||
|
||||
ext = device->DeviceExtension;
|
||||
|
@ -145,13 +160,10 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
|
|||
if (ext->ring_buffer)
|
||||
RingBuffer_Destroy(ext->ring_buffer);
|
||||
|
||||
entry = RemoveHeadList(&ext->irp_queue);
|
||||
while(entry != &ext->irp_queue)
|
||||
while((irp = pop_irp_from_queue(ext)))
|
||||
{
|
||||
irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry);
|
||||
irp->IoStatus.u.Status = STATUS_DEVICE_REMOVED;
|
||||
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||
entry = RemoveHeadList(&ext->irp_queue);
|
||||
}
|
||||
|
||||
TRACE("Delete device(%p) %s\n", device, debugstr_w(ext->device_name));
|
||||
|
@ -189,7 +201,6 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U
|
|||
|
||||
static void HID_Device_processQueue(DEVICE_OBJECT *device)
|
||||
{
|
||||
LIST_ENTRY *entry;
|
||||
IRP *irp;
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer);
|
||||
|
@ -197,11 +208,9 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device)
|
|||
|
||||
packet = HeapAlloc(GetProcessHeap(), 0, buffer_size);
|
||||
|
||||
entry = RemoveHeadList(&ext->irp_queue);
|
||||
while(entry != &ext->irp_queue)
|
||||
while((irp = pop_irp_from_queue(ext)))
|
||||
{
|
||||
int ptr;
|
||||
irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry);
|
||||
ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext );
|
||||
|
||||
RingBuffer_Read(ext->ring_buffer, ptr, packet, &buffer_size);
|
||||
|
@ -222,7 +231,6 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device)
|
|||
irp->IoStatus.u.Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
entry = RemoveHeadList(&ext->irp_queue);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, packet);
|
||||
}
|
||||
|
@ -656,9 +664,15 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp)
|
|||
BASE_DEVICE_EXTENSION *extension = device->DeviceExtension;
|
||||
if (extension->poll_interval)
|
||||
{
|
||||
KIRQL old_irql;
|
||||
TRACE_(hid_report)("Queue irp\n");
|
||||
|
||||
KeAcquireSpinLock(&ext->irp_queue_lock, &old_irql);
|
||||
|
||||
InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.s.ListEntry);
|
||||
rc = STATUS_PENDING;
|
||||
|
||||
KeReleaseSpinLock(&ext->irp_queue_lock, old_irql);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct _BASE_DEVICE_EXTENSION {
|
|||
HANDLE halt_event;
|
||||
HANDLE thread;
|
||||
|
||||
KSPIN_LOCK irp_queue_lock;
|
||||
LIST_ENTRY irp_queue;
|
||||
|
||||
/* Minidriver Specific stuff will end up here */
|
||||
|
|
|
@ -114,6 +114,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
|
|||
|
||||
ext = device->DeviceExtension;
|
||||
InitializeListHead(&ext->irp_queue);
|
||||
KeInitializeSpinLock(&ext->irp_queue_lock);
|
||||
|
||||
TRACE("Created device %p\n",device);
|
||||
status = minidriver->AddDevice(minidriver->minidriver.DriverObject, device);
|
||||
|
|
Loading…
Reference in New Issue