diff --git a/dlls/wineusb.sys/unixlib.c b/dlls/wineusb.sys/unixlib.c index f269d3e96fd..278750c37f6 100644 --- a/dlls/wineusb.sys/unixlib.c +++ b/dlls/wineusb.sys/unixlib.c @@ -51,10 +51,7 @@ struct unix_device static libusb_hotplug_callback_handle hotplug_cb_handle; -static bool thread_shutdown; - -static pthread_cond_t event_cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER; +static volatile bool thread_shutdown; static struct usb_event *usb_events; static size_t usb_event_count, usb_events_capacity; @@ -92,28 +89,21 @@ static bool array_reserve(void **elements, size_t *capacity, size_t count, size_ static void queue_event(const struct usb_event *event) { - pthread_mutex_lock(&event_mutex); if (array_reserve((void **)&usb_events, &usb_events_capacity, usb_event_count + 1, sizeof(*usb_events))) usb_events[usb_event_count++] = *event; else ERR("Failed to queue event.\n"); - pthread_mutex_unlock(&event_mutex); - pthread_cond_signal(&event_cond); } -static NTSTATUS usb_get_event(void *args) +static bool get_event(struct usb_event *event) { - const struct usb_get_event_params *params = args; + if (!usb_event_count) return false; - pthread_mutex_lock(&event_mutex); - while (!usb_event_count) - pthread_cond_wait(&event_cond, &event_mutex); - *params->event = usb_events[0]; + *event = usb_events[0]; if (--usb_event_count) memmove(usb_events, usb_events + 1, usb_event_count * sizeof(*usb_events)); - pthread_mutex_unlock(&event_mutex); - return STATUS_SUCCESS; + return true; } static void add_usb_device(libusb_device *libusb_device) @@ -239,10 +229,30 @@ static int LIBUSB_CALL hotplug_cb(libusb_context *context, libusb_device *device static NTSTATUS usb_main_loop(void *args) { - static const struct usb_event shutdown_event = {.type = USB_EVENT_SHUTDOWN}; + const struct usb_main_loop_params *params = args; int ret; - TRACE("Starting libusb event thread.\n"); + while (!thread_shutdown) + { + if (get_event(params->event)) return STATUS_PENDING; + + if ((ret = libusb_handle_events(NULL))) + ERR("Error handling events: %s\n", libusb_strerror(ret)); + } + + libusb_exit(NULL); + free(usb_events); + usb_events = NULL; + usb_event_count = usb_events_capacity = 0; + thread_shutdown = false; + + TRACE("USB main loop exiting.\n"); + return STATUS_SUCCESS; +} + +static NTSTATUS usb_init(void *args) +{ + int ret; if ((ret = libusb_init(NULL))) { @@ -260,17 +270,6 @@ static NTSTATUS usb_main_loop(void *args) return STATUS_UNSUCCESSFUL; } - while (!thread_shutdown) - { - if ((ret = libusb_handle_events(NULL))) - ERR("Error handling events: %s\n", libusb_strerror(ret)); - } - - libusb_exit(NULL); - - queue_event(&shutdown_event); - - TRACE("Shutting down libusb event thread.\n"); return STATUS_SUCCESS; } @@ -566,8 +565,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { #define X(name) [unix_ ## name] = name X(usb_main_loop), + X(usb_init), X(usb_exit), - X(usb_get_event), X(usb_submit_urb), X(usb_cancel_transfer), X(usb_destroy_device), diff --git a/dlls/wineusb.sys/unixlib.h b/dlls/wineusb.sys/unixlib.h index 0c3319969b7..eee16c8fc2b 100644 --- a/dlls/wineusb.sys/unixlib.h +++ b/dlls/wineusb.sys/unixlib.h @@ -31,7 +31,6 @@ enum usb_event_type USB_EVENT_ADD_DEVICE, USB_EVENT_REMOVE_DEVICE, USB_EVENT_TRANSFER_COMPLETE, - USB_EVENT_SHUTDOWN, }; struct usb_event @@ -53,7 +52,7 @@ struct usb_event } u; }; -struct usb_get_event_params +struct usb_main_loop_params { struct usb_event *event; }; @@ -77,8 +76,8 @@ struct usb_destroy_device_params enum unix_funcs { unix_usb_main_loop, + unix_usb_init, unix_usb_exit, - unix_usb_get_event, unix_usb_submit_urb, unix_usb_cancel_transfer, unix_usb_destroy_device, diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c index e9e91326a84..7848b31105e 100644 --- a/dlls/wineusb.sys/wineusb.c +++ b/dlls/wineusb.sys/wineusb.c @@ -165,14 +165,7 @@ static void remove_unix_device(struct unix_device *unix_device) IoInvalidateDeviceRelations(bus_pdo, BusRelations); } -static HANDLE libusb_event_thread, event_thread; - -static DWORD CALLBACK libusb_event_thread_proc(void *arg) -{ - WINE_UNIX_CALL(unix_usb_main_loop, NULL); - - return 0; -} +static HANDLE event_thread; static void complete_irp(IRP *irp) { @@ -187,18 +180,18 @@ static void complete_irp(IRP *irp) static DWORD CALLBACK event_thread_proc(void *arg) { struct usb_event event; - - TRACE("Starting client event thread.\n"); - - for (;;) + struct usb_main_loop_params params = { - struct usb_get_event_params params = - { - .event = &event, - }; + .event = &event, + }; - WINE_UNIX_CALL(unix_usb_get_event, ¶ms); + TRACE("Starting event thread.\n"); + if (WINE_UNIX_CALL(unix_usb_init, NULL) != STATUS_SUCCESS) + return 0; + + while (WINE_UNIX_CALL(unix_usb_main_loop, ¶ms) == STATUS_PENDING) + { switch (event.type) { case USB_EVENT_ADD_DEVICE: @@ -212,12 +205,11 @@ static DWORD CALLBACK event_thread_proc(void *arg) case USB_EVENT_TRANSFER_COMPLETE: complete_irp(event.u.completed_irp); break; - - case USB_EVENT_SHUTDOWN: - TRACE("Shutting down client event thread.\n"); - return 0; } } + + TRACE("Shutting down event thread.\n"); + return 0; } static NTSTATUS fdo_pnp(IRP *irp) @@ -266,7 +258,6 @@ static NTSTATUS fdo_pnp(IRP *irp) } case IRP_MN_START_DEVICE: - libusb_event_thread = CreateThread(NULL, 0, libusb_event_thread_proc, NULL, 0, NULL); event_thread = CreateThread(NULL, 0, event_thread_proc, NULL, 0, NULL); irp->IoStatus.Status = STATUS_SUCCESS; @@ -281,8 +272,6 @@ static NTSTATUS fdo_pnp(IRP *irp) struct usb_device *device, *cursor; WINE_UNIX_CALL(unix_usb_exit, NULL); - WaitForSingleObject(libusb_event_thread, INFINITE); - CloseHandle(libusb_event_thread); WaitForSingleObject(event_thread, INFINITE); CloseHandle(event_thread);