From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Victor Toso Date: Wed, 8 Feb 2017 09:59:51 +0100 Subject: [PATCH] file-xfer: avoid g_hash_table_iter_* when changing the GHashTable Using g_hash_table_iter_init() and g_hash_table_iter_next() here is bad as spice_file_transfer_task_completed() will emit "finished" signal from SpiceFileTransferTask resulting in the original GHashTable to be changed in file_transfer_operation_task_finished() Debug will show: GSpice-DEBUG: spice-file-transfer-task.c:303 File bigfile2 xfer failed: Agent connection closed WARNING **: Agent connection closed GLib-CRITICAL **: g_hash_table_iter_next: assertion 'ri->version == ri->hash_table->version' failed Reported-by: Pavel Grunt Signed-off-by: Victor Toso Acked-by: Pavel Grunt (cherry picked from commit 01bb9bb30517b0ea3bdb230d40b2835c53a9cf59) --- src/channel-main.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/channel-main.c b/src/channel-main.c index 72ca712..0a4435e 100644 --- a/src/channel-main.c +++ b/src/channel-main.c @@ -2915,19 +2915,23 @@ static void file_transfer_operation_free(FileTransferOperation *xfer_op) static void spice_main_channel_reset_all_xfer_operations(SpiceMainChannel *channel) { - GHashTableIter iter_all_xfer_tasks; - gpointer key, value; + GList *it, *keys; /* Mark each of SpiceFileTransferTask as completed due error */ - g_hash_table_iter_init(&iter_all_xfer_tasks, channel->priv->file_xfer_tasks); - while (g_hash_table_iter_next(&iter_all_xfer_tasks, &key, &value)) { - FileTransferOperation *xfer_op = value; - SpiceFileTransferTask *xfer_task = g_hash_table_lookup(xfer_op->xfer_task, key); + keys = g_hash_table_get_keys(channel->priv->file_xfer_tasks); + for (it = keys; it != NULL; it = it->next) { + FileTransferOperation *xfer_op; + SpiceFileTransferTask *xfer_task; GError *error; + xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks, it->data); + if (xfer_op == NULL) + continue; + + xfer_task = g_hash_table_lookup(xfer_op->xfer_task, it->data); if (xfer_task == NULL) { spice_warning("(reset-all) can't complete task %u - completed already?", - GPOINTER_TO_UINT(key)); + GPOINTER_TO_UINT(it->data)); continue; } @@ -2935,6 +2939,7 @@ static void spice_main_channel_reset_all_xfer_operations(SpiceMainChannel *chann "Agent connection closed"); spice_file_transfer_task_completed(xfer_task, error); } + g_list_free(keys); } static SpiceFileTransferTask *spice_main_channel_find_xfer_task_by_task_id(SpiceMainChannel *channel,