[Spice-devel] [spice-gtk v1] channel-main: improve code to use FileTransferOperation
Jonathon Jongsma
jjongsma at redhat.com
Tue Aug 9 16:33:16 UTC 2016
On Sat, 2016-08-06 at 15:26 +0200, Victor Toso wrote:
> Since commit b26818d0e00666 we are grouping all transferred files per
> operation (drag and drop); That leaded to some design flaws in the
> code. The changes suggested in this patch are (in execution order):
>
> * On spice_file_transfer_task_read_async()
> - Passing FileTransferOperation data so in the callback and in
> further
> function calls, we don't need to look for this;
>
> Note that FileTransferOperation is not freed while any of its
> SpiceFileTransferTask exists and by design they are never finished
> while on pending state, so file_xfer_read_async_cb() should have a
> valid FileTransferOperation pointer.
>
> * On file_xfer_read_async_cb()
> - Removed unnecessary variables;
>
> * On file_xfer_flush_async()
> - Using SpiceFileTransferTask as parameter which can retrieve the
> SpiceMainChannel and the GCancellable;
> - Using SpiceFileTransferTask as source_object for GTask with
> FileTransferOperation as user_data which is helpful for its
> callback;
>
> * On file_xfer_flush_finish() and file_xfer_data_flushed_cb()
> - Using SpiceFileTransferTask as parameter and source_object check
> for
> GTask
> ---
>
> Well, to be honest I thought we could benefit more with this change.
> Having the SpiceFileTransferTask on file_xfer_flush_async() had some
> code removal on file_xfer_read_async_cb() but not that much in the
> other places of the code.
>
> All in all, it makes sense to me but let me know what you think.
Sure, I think it's a slightly improvement.
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
>
> ---
> src/channel-main.c | 40 ++++++++++++++++++++++------------------
> 1 file changed, 22 insertions(+), 18 deletions(-)
>
> diff --git a/src/channel-main.c b/src/channel-main.c
> index 14ad6cf..3f91a43 100644
> --- a/src/channel-main.c
> +++ b/src/channel-main.c
> @@ -889,15 +889,22 @@ static void file_xfer_flushed(SpiceMainChannel
> *channel, gboolean success)
> GUINT_TO_POINTER(success));
> }
>
> -static void file_xfer_flush_async(SpiceMainChannel *channel,
> GCancellable *cancellable,
> - GAsyncReadyCallback callback,
> gpointer user_data)
> +static void file_xfer_flush_async(SpiceFileTransferTask *xfer_task,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> {
> GTask *task;
> - SpiceMainChannelPrivate *c = channel->priv;
> + SpiceMainChannel *channel;
> + SpiceMainChannelPrivate *c;
> gboolean was_empty;
>
> - task = g_task_new(channel, cancellable, callback, user_data);
> + channel = spice_file_transfer_task_get_channel(xfer_task);
> + task = g_task_new(xfer_task,
> + spice_file_transfer_task_get_cancellable(xfer_
> task),
> + callback,
> + user_data);
>
> + c = channel->priv;
> was_empty = g_queue_is_empty(c->agent_msg_queue);
> if (was_empty) {
> g_task_return_boolean(task, TRUE);
> @@ -909,12 +916,13 @@ static void
> file_xfer_flush_async(SpiceMainChannel *channel, GCancellable *cance
> g_hash_table_insert(c->flushing, g_queue_peek_tail(c-
> >agent_msg_queue), task);
> }
>
> -static gboolean file_xfer_flush_finish(SpiceMainChannel *channel,
> GAsyncResult *result,
> +static gboolean file_xfer_flush_finish(SpiceFileTransferTask
> *xfer_task,
> + GAsyncResult *result,
> GError **error)
> {
> GTask *task = G_TASK(result);
>
> - g_return_val_if_fail(g_task_is_valid(result, channel), FALSE);
> + g_return_val_if_fail(g_task_is_valid(result, xfer_task), FALSE);
>
> return g_task_propagate_boolean(task, error);
> }
> @@ -1756,11 +1764,10 @@ static void file_xfer_data_flushed_cb(GObject
> *source_object,
> GAsyncResult *res,
> gpointer user_data)
> {
> - SpiceFileTransferTask *xfer_task = user_data;
> - SpiceMainChannel *channel = (SpiceMainChannel *)source_object;
> + SpiceFileTransferTask *xfer_task =
> SPICE_FILE_TRANSFER_TASK(source_object);
> GError *error = NULL;
>
> - file_xfer_flush_finish(channel, res, &error);
> + file_xfer_flush_finish(xfer_task, res, &error);
> if (error) {
> spice_file_transfer_task_completed(xfer_task, error);
> return;
> @@ -1770,7 +1777,7 @@ static void file_xfer_data_flushed_cb(GObject
> *source_object,
> if (!spice_file_transfer_task_is_completed(xfer_task)) {
> file_transfer_operation_send_progress(xfer_task);
> /* Read more data */
> - spice_file_transfer_task_read_async(xfer_task,
> file_xfer_read_async_cb, NULL);
> + spice_file_transfer_task_read_async(xfer_task,
> file_xfer_read_async_cb, user_data);
> }
> }
>
> @@ -1801,11 +1808,10 @@ static void file_xfer_read_async_cb(GObject
> *source_object,
> SpiceMainChannel *channel;
> gssize count;
> char *buffer;
> - GCancellable *cancellable;
> - guint32 task_id;
> GError *error = NULL;
>
> xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
> + xfer_op = user_data;
>
> channel = spice_file_transfer_task_get_channel(xfer_task);
> count = spice_file_transfer_task_read_finish(xfer_task, res,
> &buffer, &error);
> @@ -1822,13 +1828,9 @@ static void file_xfer_read_async_cb(GObject
> *source_object,
> return;
> }
>
> - task_id = spice_file_transfer_task_get_id(xfer_task);
> - xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks,
> GUINT_TO_POINTER(task_id));
> - g_return_if_fail(xfer_op != NULL);
> xfer_op->stats.total_sent += count;
>
> - cancellable =
> spice_file_transfer_task_get_cancellable(xfer_task);
> - file_xfer_flush_async(channel, cancellable,
> file_xfer_data_flushed_cb, xfer_task);
> + file_xfer_flush_async(xfer_task, file_xfer_data_flushed_cb,
> xfer_op);
> }
>
> /* coroutine context */
> @@ -1836,17 +1838,19 @@ static void
> main_agent_handle_xfer_status(SpiceMainChannel *channel,
> VDAgentFileXferStatusMessa
> ge *msg)
> {
> SpiceFileTransferTask *xfer_task;
> + FileTransferOperation *xfer_op;
> GError *error = NULL;
>
> xfer_task =
> spice_main_channel_find_xfer_task_by_task_id(channel, msg->id);
> g_return_if_fail(xfer_task != NULL);
> + xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks,
> GUINT_TO_POINTER(msg->id));
>
> SPICE_DEBUG("xfer-task %u received response %u", msg->id, msg-
> >result);
>
> switch (msg->result) {
> case VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
> g_return_if_fail(spice_file_transfer_task_is_completed(xfer_
> task) == FALSE);
> - spice_file_transfer_task_read_async(xfer_task,
> file_xfer_read_async_cb, NULL);
> + spice_file_transfer_task_read_async(xfer_task,
> file_xfer_read_async_cb, xfer_op);
> return;
> case VD_AGENT_FILE_XFER_STATUS_CANCELLED:
> error = g_error_new(SPICE_CLIENT_ERROR,
> SPICE_CLIENT_ERROR_FAILED,
More information about the Spice-devel
mailing list