[Spice-devel] [spice-gtk] Use a GHashTable for list of file transfer tasks
Christophe Fergeau
cfergeau at redhat.com
Wed Apr 10 05:50:10 PDT 2013
This list is used to lookup tasks by their numerical id, so
a hash table is a more appropriate data structure for this kind of
uses.
---
gtk/channel-main.c | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 11cd0f9..df25cd4 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -99,7 +99,7 @@ struct _SpiceMainChannelPrivate {
} display[MAX_DISPLAY];
gint timer_id;
GQueue *agent_msg_queue;
- GList *file_xfer_task_list;
+ GHashTable *file_xfer_tasks;
GSList *flushing;
guint switch_host_delayed_id;
@@ -208,6 +208,7 @@ static void spice_main_channel_init(SpiceMainChannel *channel)
c = channel->priv = SPICE_MAIN_CHANNEL_GET_PRIVATE(channel);
c->agent_msg_queue = g_queue_new();
+ c->file_xfer_tasks = g_hash_table_new(g_direct_hash, g_direct_equal);
spice_main_channel_reset_capabilties(SPICE_CHANNEL(channel));
}
@@ -315,6 +316,8 @@ static void spice_main_channel_finalize(GObject *obj)
g_free(c->agent_msg_data);
agent_free_msg_queue(SPICE_MAIN_CHANNEL(obj));
+ if (c->file_xfer_tasks)
+ g_hash_table_unref(c->file_xfer_tasks);
if (G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize)
G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize(obj);
@@ -334,6 +337,7 @@ static void spice_main_channel_reset_agent(SpiceMainChannel *channel)
{
SpiceMainChannelPrivate *c = channel->priv;
GError *error;
+ GList *tasks;
GList *l;
c->agent_connected = FALSE;
@@ -344,13 +348,15 @@ static void spice_main_channel_reset_agent(SpiceMainChannel *channel)
c->agent_msg_data = NULL;
c->agent_msg_size = 0;
- for (l = c->file_xfer_task_list; l != NULL; l = l->next) {
+ tasks = g_hash_table_get_values(c->file_xfer_tasks);
+ for (l = tasks; l != NULL; l = l->next) {
SpiceFileXferTask *task = (SpiceFileXferTask *)l->data;
error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
"Agent connection closed");
file_xfer_completed(task, error);
}
+ g_list_free(tasks);
file_xfer_flushed(channel, FALSE);
}
@@ -1540,18 +1546,6 @@ static void main_handle_agent_disconnected(SpiceChannel *channel, SpiceMsgIn *in
agent_stopped(SPICE_MAIN_CHANNEL(channel));
}
-static gint file_xfer_task_find(gconstpointer a, gconstpointer b)
-{
- SpiceFileXferTask *task = (SpiceFileXferTask *)a;
- uint32_t id = *(uint32_t *)b;
-
- if (task->id == id) {
- return 0;
- }
-
- return 1;
-}
-
static void file_xfer_task_free(SpiceFileXferTask *task)
{
SpiceMainChannelPrivate *c;
@@ -1559,7 +1553,7 @@ static void file_xfer_task_free(SpiceFileXferTask *task)
g_return_if_fail(task != NULL);
c = task->channel->priv;
- c->file_xfer_task_list = g_list_remove(c->file_xfer_task_list, task);
+ g_hash_table_remove(c->file_xfer_tasks, GUINT_TO_POINTER(task->id));
g_clear_object(&task->channel);
g_clear_object(&task->file);
@@ -1698,17 +1692,15 @@ static void file_xfer_handle_status(SpiceMainChannel *channel,
VDAgentFileXferStatusMessage *msg)
{
SpiceMainChannelPrivate *c = channel->priv;
- GList *l;
SpiceFileXferTask *task;
GError *error = NULL;
- l = g_list_find_custom(c->file_xfer_task_list, &msg->id,
- file_xfer_task_find);
- if (l == NULL) {
+
+ task = g_hash_table_lookup(c->file_xfer_tasks, GUINT_TO_POINTER(msg->id));
+ if (task == NULL) {
SPICE_DEBUG("cannot find task %d", msg->id);
return;
}
- task = l->data;
SPICE_DEBUG("task %d received response %d", msg->id, msg->result);
@@ -2722,7 +2714,7 @@ static void file_xfer_send_start_msg_async(SpiceMainChannel *channel,
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_hash_table_insert(c->file_xfer_tasks, GUINT_TO_POINTER(task->id), task);
g_file_read_async(file,
G_PRIORITY_DEFAULT,
--
1.8.1.4
More information about the Spice-devel
mailing list