[Spice-commits] src/usb-device-manager.c

Christophe Fergau teuf at kemper.freedesktop.org
Fri Jul 1 14:27:49 UTC 2016


 src/usb-device-manager.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

New commits:
commit c0ccc8144e8554e4a8c4395f80d7e8c10d2dcfc0
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Wed Jun 29 16:57:36 2016 +0200

    usb-device-manager: Avoid USB event thread leak
    
    This is a follow-up of the previous commit ('usb-channel: Really stop
    listening for USB events on disconnection').
    
    Since the USB event thread has to be stopped when we destroy the
    associated SpiceUsbDeviceManager, spice_usb_device_manager_dispose()
    should force event_thread_run to FALSE even if
    spice_usb_device_manager_stop_event_listening() was not enough. When
    this happens, this means that there is a bug in the internal users of
    spice_usb_device_manager_start_event_listening(), but with this change,
    we'll at least warn about it, and avoid a thread leak/potential future
    crash.

diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 808ec6c..53505fa 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -375,12 +375,22 @@ static void spice_usb_device_manager_dispose(GObject *gobject)
 #ifdef USE_LIBUSB_HOTPLUG
     if (priv->hp_handle) {
         spice_usb_device_manager_stop_event_listening(self);
+        if (g_atomic_int_get(&priv->event_thread_run)) {
+            /* Force termination of the event thread even if there were some
+             * mismatched spice_usb_device_manager_{start,stop}_event_listening
+             * calls. Otherwise, the usb event thread will be leaked, and will
+             * try to use the libusb context we destroy in finalize(), which would
+             * cause a crash */
+             g_warn_if_reached();
+             g_atomic_int_set(&priv->event_thread_run, FALSE);
+        }
         /* This also wakes up the libusb_handle_events() in the event_thread */
         libusb_hotplug_deregister_callback(priv->context, priv->hp_handle);
         priv->hp_handle = 0;
     }
 #endif
-    if (priv->event_thread && !g_atomic_int_get(&priv->event_thread_run)) {
+    if (priv->event_thread) {
+        g_warn_if_fail(g_atomic_int_get(&priv->event_thread_run) == FALSE);
         g_thread_join(priv->event_thread);
         priv->event_thread = NULL;
     }


More information about the Spice-commits mailing list