Module: wine Branch: master Commit: 92456eb7471c3837018e0a34ef7a734a733aa2a7 URL: https://gitlab.winehq.org/wine/wine/-/commit/92456eb7471c3837018e0a34ef7a734...
Author: Zebediah Figura zfigura@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; }