Commit ca641a5b authored by Frediano Ziglio's avatar Frediano Ziglio

usb-device-manager: Last chance to avoid deadlock handling libusb events

Attempt to better interrupt event handling loop.
If the thread handling events is stuck waiting events or handling an
event try to interrupt before joining the thread.

For Unix code in spice_usb_device_manager_dispose will try to force
some thread exit but this is not done for Windows so calling
libusb_interrupt_event_handler will help.  Code is not in a hot path
so won't change the execution time.
Signed-off-by: Frediano Ziglio's avatarFrediano Ziglio <fziglio@redhat.com>
Acked-by: 's avatarVictor Toso <victortoso@redhat.com>
parent 397f397c
Pipeline #48111 passed with stage
in 5 minutes and 41 seconds
......@@ -230,6 +230,13 @@ gboolean spice_usb_backend_handle_events(SpiceUsbBackend *be)
return ok;
}
void spice_usb_backend_interrupt_event_handler(SpiceUsbBackend *be)
{
if (be->libusb_context) {
libusb_interrupt_event_handler(be->libusb_context);
}
}
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx,
libusb_device *device,
libusb_hotplug_event event,
......
......@@ -65,6 +65,7 @@ after it finishes list processing
SpiceUsbBackendDevice **spice_usb_backend_get_device_list(SpiceUsbBackend *backend);
void spice_usb_backend_free_device_list(SpiceUsbBackendDevice **devlist);
gboolean spice_usb_backend_handle_events(SpiceUsbBackend *be);
void spice_usb_backend_interrupt_event_handler(SpiceUsbBackend *be);
gboolean spice_usb_backend_register_hotplug(SpiceUsbBackend *be,
void *user_data,
usb_hot_plug_callback proc);
......
......@@ -328,6 +328,8 @@ static void spice_usb_device_manager_dispose(GObject *gobject)
#endif
if (priv->event_thread) {
g_warn_if_fail(g_atomic_int_get(&priv->event_thread_run) == FALSE);
g_atomic_int_set(&priv->event_thread_run, FALSE);
spice_usb_backend_interrupt_event_handler(priv->context);
g_thread_join(priv->event_thread);
priv->event_thread = NULL;
}
......@@ -988,6 +990,8 @@ gboolean spice_usb_device_manager_start_event_listening(
libusb_handle_events call in the thread won't exit until the
libusb_close call for the device is made from usbredirhost_close. */
if (priv->event_thread) {
g_atomic_int_set(&priv->event_thread_run, FALSE);
spice_usb_backend_interrupt_event_handler(priv->context);
g_thread_join(priv->event_thread);
priv->event_thread = NULL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment