<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 1 Mar 2016, at 21:14 PM, Jonathon Jongsma <<a href="mailto:jjongsma@redhat.com" class="">jjongsma@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">As I mentioned in the previous patch, I'd really like this rebased on Fabiano's</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">GTask work. I understand that it's annoying to have to rebase this stuff, so I'm</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">willing to do it for you if you'd prefer.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>That would be great, thanks. I don’t feel secure enough with GTask API to be sure I’m not introducing regressions during the rebase.</div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Another comment below</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">On Sun, 2016-02-28 at 11:54 +0200, Dmitry Fleytman wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">From: Kirill Moizik <<a href="mailto:kmoizik@redhat.com" class="">kmoizik@redhat.com</a>><br class=""><br class="">This commit introduces functions for asynchronous disconnection flows.<br class="">Following commits will make use of those.<br class=""><br class="">Thread safety is ensured the same way it was done for connection<br class="">flow in previous commits. Disconnect logic is protected by the same<br class="">locks that protect connect/usbredir/channel management logic.<br class=""><br class="">Signed-off-by: Kirill Moizik <<a href="mailto:kmoizik@redhat.com" class="">kmoizik@redhat.com</a>><br class="">Signed-off-by: Dmitry Fleytman <<a href="mailto:dfleytma@redhat.com" class="">dfleytma@redhat.com</a>><br class="">---<br class="">src/channel-usbredir-priv.h |  9 +++++++<br class="">src/channel-usbredir.c      | 42 +++++++++++++++++++++++++++++<br class="">src/map-file                |  1 +<br class="">src/usb-device-manager.c    | 66<br class="">+++++++++++++++++++++++++++++++++++++++++++++<br class="">src/usb-device-manager.h    |  8 ++++++<br class="">5 files changed, 126 insertions(+)<br class=""><br class="">diff --git a/src/channel-usbredir-priv.h b/src/channel-usbredir-priv.h<br class="">index c987474..17e9716 100644<br class="">--- a/src/channel-usbredir-priv.h<br class="">+++ b/src/channel-usbredir-priv.h<br class="">@@ -33,6 +33,15 @@ G_BEGIN_DECLS<br class="">void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel,<br class="">                                        libusb_context       *context);<br class=""><br class="">+void spice_usbredir_channel_disconnect_device_async(SpiceUsbredirChannel<br class="">*channel,<br class="">+                                                    GCancellable<br class="">*cancellable,<br class="">+                                                    GAsyncReadyCallback<br class="">callback,<br class="">+                                                    gpointer user_data);<br class="">+<br class="">+gboolean spice_usbredir_channel_disconnect_device_finish(SpiceUsbredirChannel<br class="">*channel,<br class="">+                                                         GAsyncResult        <br class="">*res,<br class="">+                                                         GError             <br class="">**err);<br class="">+<br class="">/* Note the context must be set, and the channel must be brought up<br class="">   (through spice_channel_connect()), before calling this. */<br class="">void spice_usbredir_channel_connect_device_async(<br class="">diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c<br class="">index 428c034..ebf9fce 100644<br class="">--- a/src/channel-usbredir.c<br class="">+++ b/src/channel-usbredir.c<br class="">@@ -431,6 +431,8 @@ void<br class="">spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)<br class=""><br class="">    CHANNEL_DEBUG(channel, "disconnecting device from usb channel %p",<br class="">channel);<br class=""><br class="">+    spice_usbredir_channel_lock(channel);<br class="">+<br class="">    switch (priv->state) {<br class="">    case STATE_DISCONNECTED:<br class="">    case STATE_DISCONNECTING:<br class="">@@ -464,6 +466,46 @@ void<br class="">spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)<br class="">        priv->state  = STATE_DISCONNECTED;<br class="">        break;<br class="">    }<br class="">+<br class="">+    spice_usbredir_channel_unlock(channel);<br class="">+}<br class="">+<br class="">+static void<br class="">+_disconnect_device_thread(GSimpleAsyncResult *simple,<br class="">+                          GObject *object,<br class="">+                          GCancellable *cancellable)<br class="">+{<br class="">+    spice_usbredir_channel_disconnect_device(SPICE_USBREDIR_CHANNEL(object));<br class="">+}<br class="">+<br class="">+G_GNUC_INTERNAL<br class="">+gboolean spice_usbredir_channel_disconnect_device_finish(<br class="">+                                               SpiceUsbredirChannel *channel,<br class="">+                                               GAsyncResult         *res,<br class="">+                                               GError              **err)<br class="">+{<br class="">+    return g_simple_async_result_propagate_error(G_SIMPLE_ASYNC_RESULT(res),<br class="">err);<br class="">+}<br class="">+<br class="">+void spice_usbredir_channel_disconnect_device_async(SpiceUsbredirChannel<br class="">*channel,<br class="">+                                                    GCancellable<br class="">*cancellable,<br class="">+                                                    GAsyncReadyCallback<br class="">callback,<br class="">+                                                    gpointer user_data)<br class="">+{<br class="">+    GSimpleAsyncResult* result;<br class="">+<br class="">+    result = g_simple_async_result_new(G_OBJECT(channel),<br class="">+                                       callback, user_data,<br class="">+                                      <br class="">spice_usbredir_channel_disconnect_device_async);<br class="">+<br class="">+    if (channel) {<br class="">+        g_simple_async_result_run_in_thread(result,<br class="">+                                            _disconnect_device_thread,<br class="">+                                            G_PRIORITY_DEFAULT,<br class="">+                                            cancellable);<br class="">+    } else {<br class="">+        g_simple_async_result_complete_in_idle(result);<br class="">+    }<br class="">}<br class=""><br class="">G_GNUC_INTERNAL<br class="">diff --git a/src/map-file b/src/map-file<br class="">index 92a9883..1f7755b 100644<br class="">--- a/src/map-file<br class="">+++ b/src/map-file<br class="">@@ -127,6 +127,7 @@ spice_usb_device_manager_can_redirect_device;<br class="">spice_usb_device_manager_connect_device_async;<br class="">spice_usb_device_manager_connect_device_finish;<br class="">spice_usb_device_manager_disconnect_device;<br class="">+spice_usb_device_manager_disconnect_device_async;<br class="">spice_usb_device_manager_get;<br class="">spice_usb_device_manager_get_devices;<br class="">spice_usb_device_manager_get_devices_with_filter;<br class="">diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c<br class="">index fc0f15f..93e095a 100644<br class="">--- a/src/usb-device-manager.c<br class="">+++ b/src/usb-device-manager.c<br class="">@@ -1705,6 +1705,72 @@ void<br class="">spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,<br class="">#endif<br class="">}<br class=""><br class="">+typedef struct _disconnect_cb_data<br class="">+{<br class="">+    SpiceUsbDeviceManager  *self;<br class="">+    GSimpleAsyncResult     *result;<br class="">+    SpiceUsbDevice         *device;<br class="">+} disconnect_cb_data;<br class="">+<br class="">+#ifdef USE_USBREDIR<br class="">+static<br class="">+void _disconnect_device_async_cb(GObject *gobject,<br class="">+                                 GAsyncResult *channel_res,<br class="">+                                 gpointer user_data)<br class="">+{<br class="">+    SpiceUsbredirChannel  *channel = SPICE_USBREDIR_CHANNEL(gobject);<br class="">+    disconnect_cb_data    *data    = user_data;<br class="">+    GSimpleAsyncResult    *result  = G_SIMPLE_ASYNC_RESULT(data->result);<br class="">+    GError *err = NULL;<br class="">+<br class="">+#ifdef G_OS_WIN32<br class="">+    SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(data->self);<br class="">+<br class="">+    if (self->priv->use_usbclerk) {<br class="">+        _spice_usb_device_manager_uninstall_driver_async(self, data->device);<br class="">+    }<br class="">+#endif<br class="">+<br class="">+    spice_usbredir_channel_disconnect_device_finish(channel, channel_res,<br class="">&err);<br class="">+    if (err) {<br class="">+        g_simple_async_result_take_error(result, err);<br class="">+    }<br class="">+    g_simple_async_result_complete(result);<br class="">+    g_object_unref(result);<br class="">+    g_free(data);<br class="">+}<br class="">+#endif<br class="">+<br class="">+void spice_usb_device_manager_disconnect_device_async(SpiceUsbDeviceManager<br class="">*self,<br class="">+                                                      SpiceUsbDevice *device,<br class="">+                                                      GCancellable<br class="">*cancellable,<br class="">+                                                      GAsyncReadyCallback<br class="">callback,<br class="">+                                                      gpointer user_data)<br class="">+{<br class="">+#ifdef USE_USBREDIR<br class="">+    GSimpleAsyncResult *nested;<br class="">+    g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));<br class="">+<br class="">+    g_return_if_fail(device != NULL);<br class="">+<br class="">+    SPICE_DEBUG("disconnecting device %p", device);<br class="">+<br class="">+    SpiceUsbredirChannel *channel;<br class="">+<br class="">+    channel = spice_usb_device_manager_get_channel_for_dev(self, device);<br class="">+    nested  = g_simple_async_result_new(G_OBJECT(self), callback, user_data,<br class="">+                             <br class="">spice_usb_device_manager_disconnect_device_async);<br class="">+    disconnect_cb_data *data = g_new(disconnect_cb_data, 1);<br class="">+    data->self = self;<br class="">+    data->result = nested;<br class="">+    data->device = device;<br class="">+<br class="">+    spice_usbredir_channel_disconnect_device_async(channel, cancellable,<br class="">+                                                  <br class="">_disconnect_device_async_cb,<br class="">+                                                   data);<br class="">+#endif<br class="">+}<br class="">+<br class="">/**<br class=""> * spice_usb_device_manager_can_redirect_device:<br class=""> * @self: the #SpiceUsbDeviceManager manager<br class="">diff --git a/src/usb-device-manager.h b/src/usb-device-manager.h<br class="">index e05ebae..d705e74 100644<br class="">--- a/src/usb-device-manager.h<br class="">+++ b/src/usb-device-manager.h<br class="">@@ -116,6 +116,14 @@ void spice_usb_device_manager_connect_device_async(<br class="">                                             GCancellable *cancellable,<br class="">                                             GAsyncReadyCallback callback,<br class="">                                             gpointer user_data);<br class="">+<br class="">+void spice_usb_device_manager_disconnect_device_async(<br class="">+                                             SpiceUsbDeviceManager *manager,<br class="">+                                             SpiceUsbDevice *device,<br class="">+                                             GCancellable *cancellable,<br class="">+                                             GAsyncReadyCallback callback,<br class="">+                                             gpointer user_data);<br class="">+<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">In my last review, I suggested that we should have a paired _finish() function</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">for this operation. Your reply said you added one, but it seems you only added</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">spice_usbredir_channel_disconnect_device_finish() and not</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">spice_usb_device_manager_disconnect_device_finish()</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>Right, added. Thanks.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">gboolean spice_usb_device_manager_connect_device_finish(<br class="">    SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err);<br class=""><br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Reviewed-by: Jonathon Jongsma <</span><a href="mailto:jjongsma@redhat.com" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">jjongsma@redhat.com</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">></span></div></blockquote></div><br class=""></body></html>