summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-04-27 11:42:44 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-04-27 11:42:44 -0400
commit8f15ed698bfba4f5c0fa01b4f0020888c57f473e (patch)
tree492342b2e69e91d851e5da0d19e5bcf771f06c5e
parentd8549b122481ee8f294b7bf3d9589918660d6d71 (diff)
Add _g_object_wait_for_single_ref() helper
This is needed to ensure that singletons for bus connections gets cleared properly when the bus goes away. We want this otherwise we accidentially reuse a closed bus connection. Apparently this problem never happened for me with D-Bus 1.2.x but it is pretty evident with D-Bus 1.3.x.
-rw-r--r--gdbus/tests/connection.c18
-rw-r--r--gdbus/tests/tests.c59
-rw-r--r--gdbus/tests/tests.h25
3 files changed, 98 insertions, 4 deletions
diff --git a/gdbus/tests/connection.c b/gdbus/tests/connection.c
index f0181d7..5c30959 100644
--- a/gdbus/tests/connection.c
+++ b/gdbus/tests/connection.c
@@ -100,6 +100,8 @@ test_connection_life_cycle (void)
if (!g_dbus_connection_is_closed (c))
_g_assert_signal_received (c, "closed");
g_assert (g_dbus_connection_is_closed (c));
+
+ _g_object_wait_for_single_ref (c);
g_object_unref (c);
}
@@ -313,6 +315,7 @@ test_connection_send (void)
NULL);
g_main_loop_run (loop);
+ _g_object_wait_for_single_ref (c);
g_object_unref (c);
}
@@ -513,14 +516,19 @@ test_connection_signals (void)
g_assert_cmpint (count_s2, ==, 2);
g_assert_cmpint (count_name_owner_changed, ==, 2);
- session_bus_down ();
-
g_dbus_connection_signal_unsubscribe (c1, s1);
g_dbus_connection_signal_unsubscribe (c1, s2);
g_dbus_connection_signal_unsubscribe (c1, s3);
+
+ _g_object_wait_for_single_ref (c1);
+ _g_object_wait_for_single_ref (c2);
+ _g_object_wait_for_single_ref (c3);
+
g_object_unref (c1);
g_object_unref (c2);
g_object_unref (c3);
+
+ session_bus_down ();
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -560,7 +568,9 @@ test_connection_filter (void)
session_bus_up ();
- c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ error = NULL;
+ c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ g_assert_no_error (error);
g_assert (c != NULL);
filter_id = g_dbus_connection_add_filter (c,
@@ -610,7 +620,7 @@ test_connection_filter (void)
g_object_unref (r);
g_assert_cmpint (data.num_handled, ==, 3);
-
+ _g_object_wait_for_single_ref (c);
g_object_unref (c);
g_object_unref (m);
diff --git a/gdbus/tests/tests.c b/gdbus/tests/tests.c
index 76bc35b..512ffdd 100644
--- a/gdbus/tests/tests.c
+++ b/gdbus/tests/tests.c
@@ -155,5 +155,64 @@ _g_bus_get_priv (GBusType bus_type,
return ret;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ GMainLoop *loop;
+ gboolean timed_out;
+} WaitSingleRefData;
+
+static gboolean
+on_wait_single_ref_timeout (gpointer user_data)
+{
+ WaitSingleRefData *data = user_data;
+ data->timed_out = TRUE;
+ g_main_loop_quit (data->loop);
+ return TRUE;
+}
+
+static void
+on_wait_for_single_ref_toggled (gpointer user_data,
+ GObject *object,
+ gboolean is_last_ref)
+{
+ WaitSingleRefData *data = user_data;
+ g_main_loop_quit (data->loop);
+}
+
+gboolean
+_g_object_wait_for_single_ref_do (gpointer object)
+{
+ WaitSingleRefData data;
+ guint timeout_id;
+
+ data.timed_out = FALSE;
+
+ if (G_OBJECT (object)->ref_count == 1)
+ goto out;
+
+ data.loop = g_main_loop_new (NULL, FALSE);
+ timeout_id = g_timeout_add (5 * 1000,
+ on_wait_single_ref_timeout,
+ &data);
+
+ g_object_add_toggle_ref (G_OBJECT (object),
+ on_wait_for_single_ref_toggled,
+ &data);
+ g_object_unref (object);
+
+ g_main_loop_run (data.loop);
+
+ g_object_ref (object);
+ g_object_remove_toggle_ref (object,
+ on_wait_for_single_ref_toggled,
+ &data);
+
+ g_source_remove (timeout_id);
+ g_main_loop_unref (data.loop);
+ out:
+ return data.timed_out;
+}
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/gdbus/tests/tests.h b/gdbus/tests/tests.h
index 117570e..366efdc 100644
--- a/gdbus/tests/tests.h
+++ b/gdbus/tests/tests.h
@@ -116,6 +116,31 @@ GDBusConnection *_g_bus_get_priv (GBusType bus_type,
GCancellable *cancellable,
GError **error);
+
+#define _g_object_wait_for_single_ref(object) \
+ do \
+ { \
+ if (!G_IS_OBJECT (object)) \
+ { \
+ g_assertion_message (G_LOG_DOMAIN, \
+ __FILE__, \
+ __LINE__, \
+ G_STRFUNC, \
+ "Not a GObject instance"); \
+ } \
+ if (_g_object_wait_for_single_ref_do (object)) \
+ { \
+ g_assertion_message (G_LOG_DOMAIN, \
+ __FILE__, \
+ __LINE__, \
+ G_STRFUNC, \
+ "Timed out waiting for single ref"); \
+ } \
+ } \
+ while (FALSE)
+
+gboolean _g_object_wait_for_single_ref_do (gpointer object);
+
G_END_DECLS
#endif /* __TESTS_H__ */