[gnome-builder] task: be safer when destroying secondary task data
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] task: be safer when destroying secondary task data
- Date: Thu, 9 Aug 2018 02:08:58 +0000 (UTC)
commit b3509627ad08792ea893e7f0edc033ff7293371c
Author: Christian Hergert <chergert redhat com>
Date: Wed Aug 8 19:07:55 2018 -0700
task: be safer when destroying secondary task data
If we get a second return value for the task, proxy the free request back
to the main context so that we don't hit assertions later on.
src/libide/threading/ide-task.c | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)
---
diff --git a/src/libide/threading/ide-task.c b/src/libide/threading/ide-task.c
index df60a73fa..1d8a7ef31 100644
--- a/src/libide/threading/ide-task.c
+++ b/src/libide/threading/ide-task.c
@@ -1046,6 +1046,12 @@ ide_task_return_cb (gpointer user_data)
return G_SOURCE_REMOVE;
}
+static gboolean
+ide_task_return_dummy_cb (gpointer data)
+{
+ return G_SOURCE_REMOVE;
+}
+
static void
ide_task_return (IdeTask *self,
IdeTaskResult *result)
@@ -1067,6 +1073,8 @@ ide_task_return (IdeTask *self,
if (priv->return_called)
{
+ GSource *source;
+
if (result->type == IDE_TASK_RESULT_CANCELLED)
{
/* We already had a result, and now raced to be notified of
@@ -1077,21 +1085,28 @@ ide_task_return (IdeTask *self,
return;
}
- /*
- * We already failed this task, but we need to ensure that the data
- * is released from the main context rather than potentially on a
- * thread (as we could be now).
- *
- * Since this can only happen when return_on_cancel is set, we can
- * be assured the main context is alive because that is our contract
- * with the API consumer.
+ /* If we haven't been cancelled, then we reached this path multiple
+ * times by programmer error.
*/
if (!priv->got_cancel)
- {
- /* leak result to ensure we don't free anything in the wrong context */
- g_critical ("Attempted to set task result multiple times, leaking result");
- return;
- }
+ g_critical ("Attempted to set result on task [%s] multiple times", priv->name);
+
+ /*
+ * This task has already returned, but we need to ensure that we pass
+ * the data back to the main context so that it is freed appropriately.
+ */
+
+ source = g_idle_source_new ();
+ g_source_set_name (source, "[ide-task] finalize task result");
+ g_source_set_ready_time (source, -1);
+ g_source_set_callback (source,
+ ide_task_return_dummy_cb,
+ result,
+ (GDestroyNotify)ide_task_result_free);
+ g_source_attach (source, priv->main_context);
+ g_source_unref (source);
+
+ return;
}
priv->return_called = TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]