[Spice-devel] [PATCH spice-gtk 02/16] Revert "channel-main: Fix dangling references to freed file-xfer-tasks on agent cancel"

Hans de Goede hdegoede at redhat.com
Fri Mar 29 04:40:14 PDT 2013


The fix from commit 19313a133af0d2404b29914b5937219127ad455b is incomplete,
this commit added code to file_xfer_close_cb, to remove any reference to
the task being closed from the flushing queue.

But file_xfer_flushed / file_xfer_flush_async execute file_xfer_data_flushed_cb
from an idle handler, so it is possible that when file_xfer_close_cb runs and
frees the task, it is not part of the flushing queue, but a
file_xfer_data_flushed_cb with the task as user_data argument still needs to
run, and when it will run it will refer to the now freed task.

A related problem which is also addressed in this patchset happens when we
receive a file-xfer-cancel from the agent when an async operation on the
file_stream is pending, since we then cannot call g_input_stream_close_async
on it. This is fixed in the patchset by adding a pending flag to the task
struct, and the problem with pending flushes is solved in the same way.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/channel-main.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 78ece08..257ded5 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -1546,31 +1546,17 @@ static void file_xfer_task_free(SpiceFileXferTask *task)
 }
 
 /* main context */
-static void file_xfer_remove_flush(gpointer data, gpointer user_data)
-{
-    GAsyncResult *res = G_ASYNC_RESULT(data);
-    SpiceFileXferTask *task = user_data;
-    SpiceMainChannelPrivate *c = task->channel->priv;
-
-    if (g_async_result_get_user_data(res) == task) {
-        c->flushing = g_slist_remove(c->flushing, res);
-        g_object_unref(res);
-    }
-}
-
 static void file_xfer_close_cb(GObject      *object,
                                GAsyncResult *close_res,
                                gpointer      user_data)
 {
     GSimpleAsyncResult *res;
     SpiceFileXferTask *task;
-    SpiceMainChannelPrivate *c;
     GInputStream *stream = G_INPUT_STREAM(object);
     GError *error = NULL;
 
     stream = G_INPUT_STREAM(object);
     task = user_data;
-    c = task->channel->priv;
 
     g_input_stream_close_finish(stream, close_res, &error);
     if (error) {
@@ -1594,9 +1580,6 @@ static void file_xfer_close_cb(GObject      *object,
     g_simple_async_result_complete_in_idle(res);
     g_object_unref(res);
 
-    /* On agent cancel there may be pending flushes referencing this task */
-    g_slist_foreach(c->flushing, file_xfer_remove_flush, task);
-
     file_xfer_task_free(task);
 }
 
-- 
1.8.1.4



More information about the Spice-devel mailing list