[Spice-devel] [PATCH v6 04/14] GUdevClient: Do not process USB hotplug events while redirection is in progress

Dmitry Fleytman dmitry at daynix.com
Sun Feb 28 09:54:14 UTC 2016


From: Kirill Moizik <kmoizik at redhat.com>

USB redirection flow on Windows includes a number of reset requests issued
to the port that hosts the device deing redirected.

Each port reset emulates device removal and reinsertion and produces
corresponding hotplug events and a number of device list updates on
different levels of USB stack and USB redirection engine.

As a result, queriyng USB device list performed by spice-gtk's hotplug
event handler may return inconsistent results if performed in parallel
to redirection flow.

This patch suppresses handling of USB hotplug events during redirection
and injects a simulated hotplug event after redirection completion
in order to properly process real device list changes in case they
happened during the redirection flow.

Signed-off-by: Kirill Moizik <kmoizik at redhat.com>
Signed-off-by: Dmitry Fleytman <dfleytma at redhat.com>
---
 src/win-usb-dev.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/win-usb-dev.c b/src/win-usb-dev.c
index 0503d10..cf2d7b1 100644
--- a/src/win-usb-dev.c
+++ b/src/win-usb-dev.c
@@ -293,6 +293,8 @@ static void g_udev_client_get_property(GObject     *gobject,
     }
 }
 
+static void handle_dev_change(GUdevClient *self);
+
 static void g_udev_client_set_property(GObject       *gobject,
                                        guint          prop_id,
                                        const GValue  *value,
@@ -300,10 +302,18 @@ static void g_udev_client_set_property(GObject       *gobject,
 {
     GUdevClient *self = G_UDEV_CLIENT(gobject);
     GUdevClientPrivate *priv = self->priv;
+    gboolean old_val;
 
     switch (prop_id) {
     case PROP_REDIRECTING:
+        old_val = priv->redirecting;
         priv->redirecting = g_value_get_boolean(value);
+        if (old_val && !priv->redirecting) {
+            /* This is a redirection completion case.
+               Inject hotplug event in case we missed device changes
+               during redirection processing. */
+            handle_dev_change(self);
+        }
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
@@ -399,6 +409,15 @@ static void handle_dev_change(GUdevClient *self)
     GList *now_devs = NULL;
     GList *prev, *curr; /* iterators for previous and current device lists */
 
+    if (priv->redirecting == TRUE) {
+        /* On Windows, querying USB device list may return inconsistent results
+           if performed in parallel to redirection flow.
+           A simulated hotplug event will be injected after redirection
+           completion in order to process real device list changes that may
+           had taken place during redirection process. */
+        return;
+    }
+
     if(g_udev_client_list_devices(self, &now_devs, &err, __FUNCTION__) < 0) {
         g_warning("could not retrieve device list");
         return;
-- 
2.5.0



More information about the Spice-devel mailing list