summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2023-04-27 12:46:37 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2023-04-27 12:46:37 +0000
commit6c1cbdff639ba62e482c6fbe59d526c4801ef695 (patch)
tree3be42baa8981fbb2c72c5230979cc99eff969c86
parentd231ce03645fbdc5a3c2886c76dc23ca42e27a2a (diff)
parent06eecda8235a614cfb837742e48cb233d35e6441 (diff)
downloadglib-6c1cbdff639ba62e482c6fbe59d526c4801ef695.tar.gz
Merge branch 'task-tracking' into 'main'
gtask: Track pending GTasks if G_ENABLE_DEBUG is defined See merge request GNOME/glib!3404
-rw-r--r--gio/gtask.c65
-rw-r--r--gio/gtask.h6
2 files changed, 71 insertions, 0 deletions
diff --git a/gio/gtask.c b/gio/gtask.c
index 5038cc57e..c436110aa 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -676,6 +676,58 @@ g_task_init (GTask *task)
task->check_cancellable = TRUE;
}
+#ifdef G_ENABLE_DEBUG
+G_LOCK_DEFINE_STATIC (task_list);
+static GPtrArray *task_list = NULL;
+
+void
+g_task_print_alive_tasks (void)
+{
+ GString *message_str = g_string_new ("");
+
+ G_LOCK (task_list);
+
+ if (task_list != NULL)
+ {
+ g_string_append_printf (message_str, "%u GTasks still alive:", task_list->len);
+ for (guint i = 0; i < task_list->len; i++)
+ {
+ GTask *task = g_ptr_array_index (task_list, i);
+ const gchar *name = g_task_get_name (task);
+ g_string_append_printf (message_str,
+ "\n • GTask %p, %s, ref count: %u, ever_returned: %u, completed: %u",
+ task, (name != NULL) ? name : "(no name set)",
+ ((GObject *) task)->ref_count,
+ task->ever_returned, task->completed);
+ }
+ }
+ else
+ {
+ g_string_append (message_str, "No GTasks still alive");
+ }
+
+ G_UNLOCK (task_list);
+
+ g_message ("%s", message_str->str);
+ g_string_free (message_str, TRUE);
+}
+
+static void
+g_task_constructed (GObject *object)
+{
+ GTask *task = G_TASK (object);
+
+ G_OBJECT_CLASS (g_task_parent_class)->constructed (object);
+
+ /* Track pending tasks for debugging purposes */
+ G_LOCK (task_list);
+ if (G_UNLIKELY (task_list == NULL))
+ task_list = g_ptr_array_new ();
+ g_ptr_array_add (task_list, task);
+ G_UNLOCK (task_list);
+}
+#endif /* G_ENABLE_DEBUG */
+
static void
g_task_finalize (GObject *object)
{
@@ -732,6 +784,16 @@ g_task_finalize (GObject *object)
g_cond_clear (&task->cond);
}
+ /* Track pending tasks for debugging purposes */
+#ifdef G_ENABLE_DEBUG
+ G_LOCK (task_list);
+ g_assert (task_list != NULL);
+ g_ptr_array_remove_fast (task_list, task);
+ if (G_UNLIKELY (task_list->len == 0))
+ g_clear_pointer (&task_list, g_ptr_array_unref);
+ G_UNLOCK (task_list);
+#endif /* G_ENABLE_DEBUG */
+
G_OBJECT_CLASS (g_task_parent_class)->finalize (object);
}
@@ -2316,6 +2378,9 @@ g_task_class_init (GTaskClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+#ifdef G_ENABLE_DEBUG
+ gobject_class->constructed = g_task_constructed;
+#endif
gobject_class->get_property = g_task_get_property;
gobject_class->finalize = g_task_finalize;
diff --git a/gio/gtask.h b/gio/gtask.h
index 1c2490fab..7642d2c68 100644
--- a/gio/gtask.h
+++ b/gio/gtask.h
@@ -194,6 +194,12 @@ gboolean g_task_had_error (GTask *task);
GIO_AVAILABLE_IN_2_44
gboolean g_task_get_completed (GTask *task);
+/*< private >*/
+#ifndef __GTK_DOC_IGNORE__
+/* Debugging API, not part of the public API */
+void g_task_print_alive_tasks (void);
+#endif /* !__GTK_DOC_IGNORE__ */
+
G_END_DECLS
#endif /* __G_TASK_H__ */