[PATCH spice-gtk 2/2] usb device widget: don't try to disconnect on failed connect

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When you try to redirect a usb device to the guest and it fails, we
uncheck the checkbox for this device. This causes the 'clicked' signal
to be emitted, which causes us to try to disconnect the device (which is
not currently connected, since the connect operation failed).

When we try to disconnect an unconnected device, the device manager
leaks memory and gets left in an inconsistent state because we allocate
the task data, call _set_redirecting(self, TRUE) and then return early
with the following warning printed to the terminal:

(lt-spicy:4638): GSpice-CRITICAL **: spice_usbredir_channel_disconnect_device_async: assertion 'channel != NULL' failed

To avoid this, disable signal handlers for the checkbox 'clicked'
signal while we're changing the checkbox state in response to a
connection error. In addition, add an additional check to
spice_usb_device_manager_disconnect_device_async() to ensure that the
passed device is actually connected.
---
 src/usb-device-manager.c | 1 +
 src/usb-device-widget.c  | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index cc95c68..9487f38 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1827,6 +1827,7 @@ void spice_usb_device_manager_disconnect_device_async(SpiceUsbDeviceManager *sel
     g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
 
     g_return_if_fail(device != NULL);
+    g_return_if_fail(spice_usb_device_manager_is_device_connected(self, device);
 
     SPICE_DEBUG("disconnecting device %p", device);
 
diff --git a/src/usb-device-widget.c b/src/usb-device-widget.c
index 085f640..d3ea79a 100644
--- a/src/usb-device-widget.c
+++ b/src/usb-device-widget.c
@@ -478,6 +478,7 @@ static void _disconnect_cb(GObject *gobject, GAsyncResult *res, gpointer user_da
     connect_cb_data_free(data);
 }
 
+static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data);
 static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
 {
     SpiceUsbDeviceManager *manager = SPICE_USB_DEVICE_MANAGER(gobject);
@@ -500,7 +501,12 @@ static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
         g_signal_emit(self, signals[CONNECT_FAILED], 0, device, err);
         g_error_free(err);
 
+        /* don't trigger a disconnect if connect failed */
+        g_signal_handlers_block_by_func(GTK_TOGGLE_BUTTON(data->check),
+                                        checkbox_clicked_cb, self);
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->check), FALSE);
+        g_signal_handlers_unblock_by_func(GTK_TOGGLE_BUTTON(data->check),
+                                        checkbox_clicked_cb, self);
     }
 
     connect_cb_data_free(data);
-- 
2.4.3

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]