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
|
MODULE = hidclass.sys
|
||||||
IMPORTLIB = hidclass
|
IMPORTLIB = hidclass
|
||||||
IMPORTS = ntoskrnl
|
IMPORTS = hal ntoskrnl
|
||||||
DELAYIMPORTS = setupapi hid
|
DELAYIMPORTS = setupapi hid
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
@ -126,10 +126,25 @@ error:
|
|||||||
return STATUS_UNSUCCESSFUL;
|
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)
|
void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device)
|
||||||
{
|
{
|
||||||
BASE_DEVICE_EXTENSION *ext;
|
BASE_DEVICE_EXTENSION *ext;
|
||||||
LIST_ENTRY *entry;
|
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
ext = device->DeviceExtension;
|
ext = device->DeviceExtension;
|
||||||
@ -145,13 +160,10 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
|
|||||||
if (ext->ring_buffer)
|
if (ext->ring_buffer)
|
||||||
RingBuffer_Destroy(ext->ring_buffer);
|
RingBuffer_Destroy(ext->ring_buffer);
|
||||||
|
|
||||||
entry = RemoveHeadList(&ext->irp_queue);
|
while((irp = pop_irp_from_queue(ext)))
|
||||||
while(entry != &ext->irp_queue)
|
|
||||||
{
|
{
|
||||||
irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry);
|
|
||||||
irp->IoStatus.u.Status = STATUS_DEVICE_REMOVED;
|
irp->IoStatus.u.Status = STATUS_DEVICE_REMOVED;
|
||||||
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||||
entry = RemoveHeadList(&ext->irp_queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Delete device(%p) %s\n", device, debugstr_w(ext->device_name));
|
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)
|
static void HID_Device_processQueue(DEVICE_OBJECT *device)
|
||||||
{
|
{
|
||||||
LIST_ENTRY *entry;
|
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||||
UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer);
|
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);
|
packet = HeapAlloc(GetProcessHeap(), 0, buffer_size);
|
||||||
|
|
||||||
entry = RemoveHeadList(&ext->irp_queue);
|
while((irp = pop_irp_from_queue(ext)))
|
||||||
while(entry != &ext->irp_queue)
|
|
||||||
{
|
{
|
||||||
int ptr;
|
int ptr;
|
||||||
irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry);
|
|
||||||
ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext );
|
ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext );
|
||||||
|
|
||||||
RingBuffer_Read(ext->ring_buffer, ptr, packet, &buffer_size);
|
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;
|
irp->IoStatus.u.Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||||
entry = RemoveHeadList(&ext->irp_queue);
|
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, packet);
|
HeapFree(GetProcessHeap(), 0, packet);
|
||||||
}
|
}
|
||||||
@ -656,9 +664,15 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp)
|
|||||||
BASE_DEVICE_EXTENSION *extension = device->DeviceExtension;
|
BASE_DEVICE_EXTENSION *extension = device->DeviceExtension;
|
||||||
if (extension->poll_interval)
|
if (extension->poll_interval)
|
||||||
{
|
{
|
||||||
|
KIRQL old_irql;
|
||||||
TRACE_(hid_report)("Queue irp\n");
|
TRACE_(hid_report)("Queue irp\n");
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&ext->irp_queue_lock, &old_irql);
|
||||||
|
|
||||||
InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.s.ListEntry);
|
InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.s.ListEntry);
|
||||||
rc = STATUS_PENDING;
|
rc = STATUS_PENDING;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&ext->irp_queue_lock, old_irql);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,7 @@ typedef struct _BASE_DEVICE_EXTENSION {
|
|||||||
HANDLE halt_event;
|
HANDLE halt_event;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
|
||||||
|
KSPIN_LOCK irp_queue_lock;
|
||||||
LIST_ENTRY irp_queue;
|
LIST_ENTRY irp_queue;
|
||||||
|
|
||||||
/* Minidriver Specific stuff will end up here */
|
/* Minidriver Specific stuff will end up here */
|
||||||
|
@ -114,6 +114,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
|
|||||||
|
|
||||||
ext = device->DeviceExtension;
|
ext = device->DeviceExtension;
|
||||||
InitializeListHead(&ext->irp_queue);
|
InitializeListHead(&ext->irp_queue);
|
||||||
|
KeInitializeSpinLock(&ext->irp_queue_lock);
|
||||||
|
|
||||||
TRACE("Created device %p\n",device);
|
TRACE("Created device %p\n",device);
|
||||||
status = minidriver->AddDevice(minidriver->minidriver.DriverObject, device);
|
status = minidriver->AddDevice(minidriver->minidriver.DriverObject, device);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user