[next] telepathy-glib: tp_tests_await_last_unref: add
Simon McVittie
smcv at kemper.freedesktop.org
Tue Mar 18 05:45:05 PDT 2014
Module: telepathy-glib
Branch: next
Commit: 64f58b0b6c3da84b154c33488627205c58524176
URL: http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=64f58b0b6c3da84b154c33488627205c58524176
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Mon Mar 17 15:04:19 2014 +0000
tp_tests_await_last_unref: add
---
tests/lib/util.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/lib/util.h | 15 ++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/tests/lib/util.c b/tests/lib/util.c
index a09199b..3efd3fb 100644
--- a/tests/lib/util.c
+++ b/tests/lib/util.c
@@ -27,6 +27,8 @@
#include <gio/gunixconnection.h>
#endif
+#include "debug.h"
+
void
tp_tests_proxy_run_until_prepared (gpointer proxy,
const GQuark *features)
@@ -779,3 +781,60 @@ _tp_tests_assert_last_unref (gpointer obj,
g_error ("%s:%d: %s %p should not have had any more references",
file, line, G_OBJECT_TYPE_NAME (obj), obj);
}
+
+/*
+ * tp_tests_await_last_unref:
+ * @op: a pointer to a #GObject
+ *
+ * Set @op to point to %NULL, release one reference to the object to which
+ * it previously pointed, and wait for that object to be freed by iterating
+ * the default (NULL) main-context.
+ *
+ * For instance, suppose you have this code, and you want to adapt it to
+ * assert that @obj is not leaked:
+ *
+ * |[
+ * obj = my_object_new ();
+ * my_object_do_thing_async (obj, NULL, NULL);
+ * g_clear_object (&obj);
+ * ]|
+ *
+ * Because #GAsyncResult async calls take a ref to the
+ * source object for the duration of the async call, this will cause
+ * an assertion failure:
+ *
+ * |[
+ * obj = my_object_new ();
+ * my_object_do_thing_async (obj, NULL, NULL);
+ * tp_tests_assert_last_unref (&obj);
+ * ]|
+ *
+ * but this is OK, and will wait for the `do_thing_async` call to finish:
+ *
+ * |[
+ * obj = my_object_new ();
+ * my_object_do_thing_async (obj, NULL, NULL);
+ * tp_tests_await_last_unref (&obj);
+ * ]|
+ */
+/* Really a macro, this is its implementation. @obj is the original `*op` */
+void
+_tp_tests_await_last_unref (gpointer obj,
+ const gchar *file,
+ int line)
+{
+ GWeakRef weak;
+
+ g_weak_ref_init (&weak, obj);
+ g_object_unref (obj);
+ obj = g_weak_ref_get (&weak);
+
+ while (obj != NULL)
+ {
+ DEBUG ("%s %p still has references, waiting...",
+ G_OBJECT_TYPE_NAME (obj), obj);
+ g_object_unref (obj);
+ g_main_context_iteration (NULL, TRUE);
+ obj = g_weak_ref_get (&weak);
+ }
+}
diff --git a/tests/lib/util.h b/tests/lib/util.h
index b82ead8..fbfb8f8 100644
--- a/tests/lib/util.h
+++ b/tests/lib/util.h
@@ -108,6 +108,21 @@ TpChannel *tp_tests_channel_new_from_properties (TpConnection *conn,
GHashTable * tp_tests_dup_channel_props_asv (TpChannel *channel);
+#define tp_tests_await_last_unref(op) \
+ G_STMT_START \
+ { \
+ gpointer _tmp; \
+ \
+ _tmp = *(op); \
+ *(op) = NULL; \
+ \
+ _tp_tests_await_last_unref (_tmp, __FILE__, __LINE__); \
+ } \
+ G_STMT_END
+void _tp_tests_await_last_unref (gpointer obj,
+ const gchar *file,
+ int line);
+
#define tp_tests_assert_last_unref(op) \
G_STMT_START \
{ \
More information about the telepathy-commits
mailing list