diff options
author | Kirill Moizik <kmoizik@redhat.com> | 2016-03-08 16:05:51 +0200 |
---|---|---|
committer | Jonathon Jongsma <jjongsma@redhat.com> | 2016-03-24 11:00:01 -0500 |
commit | b4b4187813cdd6c137915bf3967bfaeac0f14a36 (patch) | |
tree | 3cb107ab61ff7047d480bbcb755010aeba212d15 | |
parent | 4ec353ea4c156063128af32a0bfcdfa7358c4d56 (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.c | 19 |
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; |