Zebediah Figura : ntoskrnl/tests: Also test that IoInvalidateDeviceRelations() during device enumeration doesn't deadlock.

Alexandre Julliard julliard at winehq.org
Mon Jul 11 15:51:38 CDT 2022


Module: wine
Branch: master
Commit: 92456eb7471c3837018e0a34ef7a734a733aa2a7
URL:    https://gitlab.winehq.org/wine/wine/-/commit/92456eb7471c3837018e0a34ef7a734a733aa2a7

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Sat Jul  9 16:15:15 2022 -0500

ntoskrnl/tests: Also test that IoInvalidateDeviceRelations() during device enumeration doesn't deadlock.

wineusb enumerates new devices and completes IRPs from the same thread (as if it
were an IRQ thread). On the other hand, the Hauppauge cx231xx USB driver
performs I/O from within IRP_MN_START_DEVICE. If the wineusb "IRQ" thread is
currently trying to report a new device, it won't be able to report I/O
completion, resulting in a deadlock.

Although wineusb could be modified to use more threads, these tests show that
calling IoInvalidateDeviceRelations() should not block in this situation.

---

 dlls/ntoskrnl.exe/tests/driver_pnp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c
index a3e7329ae72..4b269f00bfc 100644
--- a/dlls/ntoskrnl.exe/tests/driver_pnp.c
+++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c
@@ -275,6 +275,8 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
             todo_wine ok(!status, "Failed to wait for child plug event, status %#lx.\n", status);
             status = ZwSetEvent(device->plug_event2, NULL);
             ok(!status, "Failed to set event, status %#lx.\n", status);
+            status = ZwWaitForSingleObject(device->plug_event, TRUE, &wait_time);
+            todo_wine ok(!status, "Failed to wait for child plug event, status %#lx.\n", status);
 
             ret = STATUS_SUCCESS;
             break;
@@ -648,6 +650,10 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code)
             ok(!status, "Failed to set event, status %#lx.\n", status);
             status = ZwWaitForSingleObject(device->plug_event2, TRUE, &wait_time);
             ok(!status, "Failed to wait for child plug event, status %#lx.\n", status);
+            /* IoInvalidateDeviceRelations() here shouldn't deadlock either. */
+            IoInvalidateDeviceRelations(bus_pdo, BusRelations);
+            status = ZwSetEvent(device->plug_event, NULL);
+            ok(!status, "Failed to set event, status %#lx.\n", status);
 
             return STATUS_SUCCESS;
         }




More information about the wine-cvs mailing list