summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Moizik <kmoizik@redhat.com>2016-03-08 16:05:51 +0200
committerJonathon Jongsma <jjongsma@redhat.com>2016-03-24 11:00:01 -0500
commitb4b4187813cdd6c137915bf3967bfaeac0f14a36 (patch)
tree3cb107ab61ff7047d480bbcb755010aeba212d15
parent4ec353ea4c156063128af32a0bfcdfa7358c4d56 (diff)
GUdevClient: Do not process USB hotplug events while redirection is in progress
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@redhat.com> Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com> Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
-rw-r--r--src/win-usb-dev.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/win-usb-dev.c b/src/win-usb-dev.c
index 0e86d39..1cf9f21 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);
@@ -412,6 +422,15 @@ static void handle_dev_change(GUdevClient *self)
GError *err = NULL;
GList *now_devs = NULL;
+ 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;