Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- gtk/channel-main.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/gtk/channel-main.c b/gtk/channel-main.c index 1ae300c..ad6c0c6 100644 --- a/gtk/channel-main.c +++ b/gtk/channel-main.c @@ -69,6 +69,7 @@ typedef struct SpiceFileXferTask { uint64_t read_bytes; uint64_t file_size; GError *error; + GError *cancelled; } SpiceFileXferTask; struct _SpiceMainChannelPrivate { @@ -332,6 +333,8 @@ static void spice_channel_iterate_write(SpiceChannel *channel) static void spice_main_channel_reset_agent(SpiceMainChannel *channel) { SpiceMainChannelPrivate *c = channel->priv; + GError *error; + GList *l; c->agent_connected = FALSE; c->agent_caps_received = FALSE; @@ -340,6 +343,21 @@ static void spice_main_channel_reset_agent(SpiceMainChannel *channel) g_free(c->agent_msg_data); c->agent_msg_data = NULL; c->agent_msg_size = 0; + + for (l = c->file_xfer_task_list; l != NULL; l = l->next) { + SpiceFileXferTask *task = (SpiceFileXferTask *)l->data; + + if (task->closed || task->cancelled) + continue; + + error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + "Agent connection closed"); + if (task->file_stream == NULL || + g_input_stream_has_pending(G_INPUT_STREAM(task->file_stream))) + task->cancelled = error; + else + file_xfer_completed(task, error); + } } /* main or coroutine context */ @@ -1627,6 +1645,14 @@ static void file_xfer_read_cb(GObject *source_object, count = g_input_stream_read_finish(G_INPUT_STREAM(task->file_stream), res, &error); + + if (task->cancelled) { + g_clear_error(&error); + file_xfer_completed(task, task->cancelled); + task->cancelled = NULL; + return; + } + if (count > 0) { task->read_bytes += count; file_xfer_queue(task, count); @@ -2602,9 +2628,13 @@ static void file_xfer_info_async_cb(GObject *obj, GAsyncResult *res, gpointer da gsize /*msg_size*/ data_len; gchar *string; SpiceFileXferTask *task = (SpiceFileXferTask *)data; - SpiceMainChannelPrivate *c = task->channel->priv; info = g_file_query_info_finish(file, res, &error); + if (task->cancelled) { + g_clear_error(&error); + error = task->cancelled; + task->cancelled = NULL; + } if (error) goto failed; @@ -2627,9 +2657,6 @@ static void file_xfer_info_async_cb(GObject *obj, GAsyncResult *res, gpointer da goto failed; /* Create file-xfer start message */ - CHANNEL_DEBUG(task->channel, "Insert a xfer task:%d to task list", task->id); - c->file_xfer_task_list = g_list_append(c->file_xfer_task_list, task); - msg.id = task->id; agent_msg_queue_many(task->channel, VD_AGENT_FILE_XFER_START, &msg, sizeof(msg), @@ -2649,6 +2676,11 @@ static void file_xfer_read_async_cb(GObject *obj, GAsyncResult *res, gpointer da GError *error = NULL; task->file_stream = g_file_read_finish(file, res, &error); + if (task->cancelled) { + g_clear_error(&error); + error = task->cancelled; + task->cancelled = NULL; + } if (error) { task->error = error; file_xfer_close_cb(NULL, NULL, task); @@ -2673,6 +2705,7 @@ static void file_xfer_send_start_msg_async(SpiceMainChannel *channel, GAsyncReadyCallback callback, gpointer user_data) { + SpiceMainChannelPrivate *c = channel->priv; SpiceFileXferTask *task; static uint32_t xfer_id; /* Used to identify task id */ @@ -2687,6 +2720,9 @@ static void file_xfer_send_start_msg_async(SpiceMainChannel *channel, task->callback = callback; task->user_data = user_data; + CHANNEL_DEBUG(task->channel, "Insert a xfer task:%d to task list", task->id); + c->file_xfer_task_list = g_list_append(c->file_xfer_task_list, task); + g_file_read_async(file, G_PRIORITY_DEFAULT, cancellable, -- 1.8.1.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel