Instead of calling process_hid_report.
We need to guard the event queue as the input reports are read from dedicated threads.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index e26e11c720d..45c5b2e151a 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -648,6 +648,7 @@ static DWORD CALLBACK device_report_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; struct platform_private *private = impl_from_DEVICE_OBJECT(device); + struct unix_device *iface = &private->unix_device; struct pollfd plfds[2];
plfds[0].fd = private->device_fd; @@ -671,7 +672,11 @@ static DWORD CALLBACK device_report_thread(void *args) else if (size == 0) TRACE_(hid_report)("Failed to read report\n"); else - process_hid_report(device, report_buffer, size); + { + EnterCriticalSection(&udev_cs); + bus_event_queue_input_report(&event_queue, iface, report_buffer, size); + LeaveCriticalSection(&udev_cs); + } } return 0; } @@ -876,6 +881,7 @@ static DWORD CALLBACK lnxev_device_report_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; struct wine_input_private *private = input_impl_from_DEVICE_OBJECT(device); + struct unix_device *iface = &private->base.unix_device; struct pollfd plfds[2];
plfds[0].fd = private->base.device_fd; @@ -899,7 +905,11 @@ static DWORD CALLBACK lnxev_device_report_thread(void *args) else if (size == 0) TRACE_(hid_report)("Failed to read report\n"); else if (set_report_from_event(private, &ie)) - process_hid_report(device, private->current_report_buffer, private->buffer_length); + { + EnterCriticalSection(&udev_cs); + bus_event_queue_input_report(&event_queue, iface, private->current_report_buffer, private->buffer_length); + LeaveCriticalSection(&udev_cs); + } } return 0; } @@ -1276,16 +1286,27 @@ NTSTATUS udev_bus_wait(void *args) pfd[1].events = POLLIN; pfd[1].revents = 0;
+ /* cleanup previously returned event */ + bus_event_cleanup(result); + while (1) { - if (bus_event_queue_pop(&event_queue, result)) return STATUS_PENDING; + EnterCriticalSection(&udev_cs); + if (bus_event_queue_pop(&event_queue, result)) + { + LeaveCriticalSection(&udev_cs); + return STATUS_PENDING; + } + LeaveCriticalSection(&udev_cs); if (poll(pfd, 2, -1) <= 0) continue; if (pfd[1].revents) break; process_monitor_event(udev_monitor); }
TRACE("UDEV main loop exiting\n"); + EnterCriticalSection(&udev_cs); bus_event_queue_destroy(&event_queue); + LeaveCriticalSection(&udev_cs); udev_monitor_unref(udev_monitor); udev_unref(udev_context); udev_context = NULL;