[Spice-devel] [PATCH v2 4/6] Make start redirection asynchronous

Kirill Moizik kirill at daynix.com
Mon Jul 6 10:59:04 PDT 2015


1)grey out usbredirection widget
2)start async redirection
3)on finish callback update state, update list of devices (we need to do it since we cant query device list while redirecting, so we could  miss device changes)
4)ungrey widget

Signed-off-by: Kirill Moizik <kmoizik at redhat.com>
---
 src/channel-usbredir.c   | 34 ++++++++++++++++++++++++----------
 src/usb-device-manager.c | 10 +++++-----
 src/usb-device-widget.c  | 30 +++++++++++++++++++++++++-----
 3 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index 292b82f..e7d5949 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -308,6 +308,25 @@ static void spice_usbredir_channel_open_acl_cb(
 }
 #endif
 
+#ifndef USE_POLKIT
+static void
+spice_usbredir_channel_open_device_async(GSimpleAsyncResult *simple,
+                                         GObject *object,
+                                         GCancellable *cancellable)
+{
+    GError *err = NULL;
+    SpiceUsbredirChannel *channel= (SpiceUsbredirChannel *)object;
+    SpiceUsbredirChannelPrivate *priv = channel->priv;
+    if (!spice_usbredir_channel_open_device(channel, &err)) {
+        g_simple_async_result_take_error(simple, err);
+        libusb_unref_device(priv->device);
+        priv->device = NULL;
+        g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
+        priv->spice_device = NULL;
+     }
+}
+#endif
+
 G_GNUC_INTERNAL
 void spice_usbredir_channel_connect_device_async(
                                           SpiceUsbredirChannel *channel,
@@ -319,9 +338,6 @@ void spice_usbredir_channel_connect_device_async(
 {
     SpiceUsbredirChannelPrivate *priv = channel->priv;
     GSimpleAsyncResult *result;
-#if ! USE_POLKIT
-    GError *err = NULL;
-#endif
 
     g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel));
     g_return_if_fail(device != NULL);
@@ -362,13 +378,11 @@ void spice_usbredir_channel_connect_device_async(
                                   channel);
     return;
 #else
-    if (!spice_usbredir_channel_open_device(channel, &err)) {
-        g_simple_async_result_take_error(result, err);
-        libusb_unref_device(priv->device);
-        priv->device = NULL;
-        g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
-        priv->spice_device = NULL;
-    }
+    g_simple_async_result_run_in_thread(result,
+                                        spice_usbredir_channel_open_device_async,
+                                        G_PRIORITY_DEFAULT,
+                                        cancellable);
+    return;
 #endif
 
 done:
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 1b334d3..c07ba03 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1455,6 +1455,7 @@ gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *sel
     return !!spice_usb_device_manager_get_channel_for_dev(self, device);
 }
 
+#ifdef USE_USBREDIR
 /**
  * spice_usb_device_manager_connect_device_async:
  * @manager: the #SpiceUsbDeviceManager manager
@@ -1480,7 +1481,6 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
     result = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
                                spice_usb_device_manager_connect_device_async);
 
-#ifdef USE_USBREDIR
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
     libusb_device *libdev;
     guint i;
@@ -1526,18 +1526,16 @@ _spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
         libusb_unref_device(libdev);
         return;
     }
-#endif
 
     g_simple_async_result_set_error(result,
                             SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
                             _("No free USB channel"));
-#ifdef USE_USBREDIR
 done:
-#endif
     g_simple_async_result_complete_in_idle(result);
     g_object_unref(result);
 }
 
+#endif
 
 void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
                                              SpiceUsbDevice *device,
@@ -1545,8 +1543,9 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
                                              GAsyncReadyCallback callback,
                                              gpointer user_data)
 {
+#ifdef USE_USBREDIR
     if (self->priv->use_usbclerk) {
-#if defined(USE_USBREDIR) && defined(G_OS_WIN32)
+#ifdef G_OS_WIN32
         SpiceWinUsbDriver *installer;
         UsbInstallCbInfo *cbinfo;
 
@@ -1576,6 +1575,7 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
                                                        callback,
                                                        user_data);
     }
+#endif
 }
 
 gboolean spice_usb_device_manager_connect_device_finish(
diff --git a/src/usb-device-widget.c b/src/usb-device-widget.c
index 72f3b34..a3e89f6 100644
--- a/src/usb-device-widget.c
+++ b/src/usb-device-widget.c
@@ -26,6 +26,17 @@
 #include "spice-marshal.h"
 #include "usb-device-widget.h"
 
+#ifdef USE_USBREDIR
+#if defined(USE_GUDEV)
+#include <gudev/gudev.h>
+#elif defined(G_OS_WIN32)
+#include "win-usb-dev.h"
+#define USE_GUDEV /* win-usb-dev.h provides a fake gudev interface */
+#elif !defined USE_LIBUSB_HOTPLUG
+#error "Expecting one of USE_GUDEV or USE_LIBUSB_HOTPLUG to be defined"
+#endif
+#endif
+
 /**
  * SECTION:usb-device-widget
  * @short_description: USB device selection widget
@@ -406,6 +417,12 @@ static gboolean spice_usb_device_widget_update_status(gpointer user_data)
     SpiceUsbDeviceWidgetPrivate *priv = self->priv;
 
     priv->device_count = 0;
+    gboolean redirecting;
+    g_object_get(priv->manager, "redirecting", &redirecting, NULL);
+
+    if (redirecting) {
+        return FALSE;
+    }
     gtk_container_foreach(GTK_CONTAINER(self), check_can_redirect, self);
 
     if (priv->err_msg) {
@@ -477,9 +494,9 @@ static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
         g_error_free(err);
 
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->check), FALSE);
-        spice_usb_device_widget_update_status(self);
-    }
 
+    }
+    spice_usb_device_widget_update_status(self);
     g_object_unref(data->check);
     g_object_unref(data->self);
     g_free(data);
@@ -492,11 +509,12 @@ static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data)
     SpiceUsbDevice *device;
 
     device = g_object_get_data(G_OBJECT(check), "usb-device");
+    connect_cb_data *data = g_new(connect_cb_data, 1);
+    data->check = g_object_ref(check);
+    data->self  = g_object_ref(self);
+    set_redirecting(self, TRUE);
 
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
-        connect_cb_data *data = g_new(connect_cb_data, 1);
-        data->check = g_object_ref(check);
-        data->self  = g_object_ref(self);
         spice_usb_device_manager_connect_device_async(priv->manager,
                                                       device,
                                                       NULL,
@@ -521,6 +539,8 @@ static void device_added_cb(SpiceUsbDeviceManager *manager,
     SpiceUsbDeviceWidgetPrivate *priv = self->priv;
     GtkWidget *align, *check;
     gchar *desc;
+    gboolean redirecting;
+    g_object_get(priv->manager, "redirecting", &redirecting, NULL);
 
     desc = spice_usb_device_get_description(device,
                                             priv->device_format_string);
-- 
2.1.0



More information about the Spice-devel mailing list