Jacek Caban : hidclass.sys: Make read IRP queue thread safe.
Alexandre Julliard
julliard at winehq.org
Thu May 9 13:32:43 CDT 2019
Module: wine
Branch: master
Commit: 85082e8bd3c9bcb0b45fc56b55cc7c88c653d028
URL: https://source.winehq.org/git/wine.git/?a=commit;h=85082e8bd3c9bcb0b45fc56b55cc7c88c653d028
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed May 8 23:09:03 2019 +0200
hidclass.sys: Make read IRP queue thread safe.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/hidclass.sys/Makefile.in | 2 +-
dlls/hidclass.sys/device.c | 34 ++++++++++++++++++++++++----------
dlls/hidclass.sys/hid.h | 1 +
dlls/hidclass.sys/pnp.c | 1 +
4 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in
index e942217..209c2df 100644
--- a/dlls/hidclass.sys/Makefile.in
+++ b/dlls/hidclass.sys/Makefile.in
@@ -1,6 +1,6 @@
MODULE = hidclass.sys
IMPORTLIB = hidclass
-IMPORTS = ntoskrnl
+IMPORTS = hal ntoskrnl
DELAYIMPORTS = setupapi hid
C_SRCS = \
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 81d5c3c..fcdb1b8 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -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
{
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 769b715..ff2e7ef 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -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 */
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 08aae15..a283d63 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -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);
More information about the wine-cvs
mailing list