diff options
author | Hans de Goede <hdegoede@redhat.com> | 2011-11-08 14:52:10 +0100 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2011-11-16 17:06:59 +0100 |
commit | 012f2de1215b2f654571e2ca924f106c24315ba4 (patch) | |
tree | a9d5c25df8b5f7bc22effa43f0ae62be1cc0b28f | |
parent | 47d7c79be52f23b663e48af4eaeaba32dc486c43 (diff) | |
download | spice-gtk-012f2de1215b2f654571e2ca924f106c24315ba4.tar.gz spice-gtk-012f2de1215b2f654571e2ca924f106c24315ba4.tar.xz spice-gtk-012f2de1215b2f654571e2ca924f106c24315ba4.zip |
channel-usbredir: Make spice_usbredir_channel_connect async
With the (upcoming) introduction of the usb device node acl helper, which
uses policykit, spice_usbredir_channel_connect() may take a long time as
it will be waiting for the helper, which will be waiting for policykit which
may be interacting with the user -> Make spice_usbredir_channel_connect() async
Note that this patch only changes spice_usbredir_channel_connect's
API to use the standard GIO async API, it is not actually async after this
patch since it does not yet call the acl helper.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r-- | gtk/channel-usbredir-priv.h | 14 | ||||
-rw-r--r-- | gtk/channel-usbredir.c | 49 | ||||
-rw-r--r-- | gtk/usb-device-manager.c | 29 |
3 files changed, 73 insertions, 19 deletions
diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h index 05988e1..8bb42a5 100644 --- a/gtk/channel-usbredir-priv.h +++ b/gtk/channel-usbredir-priv.h @@ -28,10 +28,16 @@ G_BEGIN_DECLS -gboolean spice_usbredir_channel_connect(SpiceUsbredirChannel *channel, - GUsbContext *context, - GUsbDevice *device, - GError **err); +void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel, + GUsbContext *context, + GUsbDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean spice_usbredir_channel_connect_finish(SpiceUsbredirChannel *channel, + GAsyncResult *res, + GError **err); + void spice_usbredir_channel_disconnect(SpiceUsbredirChannel *channel); GUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel); diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c index 4194b48..fd54594 100644 --- a/gtk/channel-usbredir.c +++ b/gtk/channel-usbredir.c @@ -153,27 +153,60 @@ static gboolean spice_usbredir_channel_open_device( } G_GNUC_INTERNAL -gboolean spice_usbredir_channel_connect(SpiceUsbredirChannel *channel, - GUsbContext *context, - GUsbDevice *device, - GError **err) +void spice_usbredir_channel_connect_async(SpiceUsbredirChannel *channel, + GUsbContext *context, + GUsbDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { SpiceUsbredirChannelPrivate *priv = channel->priv; + GSimpleAsyncResult *result; + GError *err = NULL; - g_return_val_if_fail(err == NULL || *err == NULL, FALSE); + g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel)); + g_return_if_fail(context != NULL); + g_return_if_fail(device != NULL); SPICE_DEBUG("connecting usb channel %p", channel); - spice_channel_disconnect(SPICE_CHANNEL(channel), SPICE_CHANNEL_NONE); + result = g_simple_async_result_new(G_OBJECT(channel), callback, user_data, + spice_usbredir_channel_connect_async); + + if (priv->device) { + g_simple_async_result_set_error(result, + SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + "Error channel is busy"); + goto done; + } priv->context = g_object_ref(context); priv->device = g_object_ref(device); - if (!spice_usbredir_channel_open_device(channel, err)) { + if (!spice_usbredir_channel_open_device(channel, &err)) { + g_simple_async_result_take_error(result, err); g_clear_object(&priv->context); g_clear_object(&priv->device); - return FALSE; } +done: + g_simple_async_result_complete_in_idle(result); + g_object_unref(result); +} + +G_GNUC_INTERNAL +gboolean spice_usbredir_channel_connect_finish(SpiceUsbredirChannel *channel, + GAsyncResult *res, + GError **err) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(res); + + g_return_val_if_fail(g_simple_async_result_is_valid(res, G_OBJECT(channel), + spice_usbredir_channel_connect_async), + FALSE); + + if (g_simple_async_result_propagate_error(result, err)) + return FALSE; + return TRUE; } diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c index 9b02066..b1d6c95 100644 --- a/gtk/usb-device-manager.c +++ b/gtk/usb-device-manager.c @@ -480,6 +480,21 @@ static void spice_usb_device_manager_dev_removed(GUsbDeviceList *devlist, g_signal_emit(manager, signals[DEVICE_REMOVED], 0, device); g_ptr_array_remove(priv->devices, device); } + +static void spice_usb_device_manager_channel_connect_cb( + GObject *gobject, GAsyncResult *channel_res, gpointer user_data) +{ + SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject); + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(user_data); + GError *err = NULL; + + spice_usbredir_channel_connect_finish(channel, channel_res, &err); + if (err) { + g_simple_async_result_take_error(result, err); + } + g_simple_async_result_complete(result); + g_object_unref(result); +} #endif /* ------------------------------------------------------------------ */ @@ -635,13 +650,13 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, if (spice_usbredir_channel_get_device(channel)) continue; /* Skip already used channels */ - if (!spice_usbredir_channel_connect(channel, priv->context, - (GUsbDevice *)device, &e)) { - g_simple_async_result_take_error(result, e); - goto done; - } - - goto done; + spice_usbredir_channel_connect_async(channel, + priv->context, + (GUsbDevice *)device, + cancellable, + spice_usb_device_manager_channel_connect_cb, + result); + return; } #endif |