From d704f02119a888bd0a43b0ce0fac7d1ddc5d2df7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 21 Jun 2019 09:51:15 +0200 Subject: [PATCH] libnm: workaround assertion failure for nmtst_connection_assert_unchanging() when disposing connection nmtst_connection_assert_unchanging() registers to the changed signals and asserts that they are not invoked. The purpose is that sometimes we want to keep a reference to an NMConnection and be sure that it does not get modified. This allows everybody to keep a reference to the very same connection instance without cloning it -- provided they too promise not to change it. This assert is to ensure that. Note that NMSimpleConnection.dispose() clears the secrets and thus upon destruction the assertion fails. At that point, the assertion is no longer relevant, because the purpose was to ensure that no alive instances gets modified. While destroying the instance, it's fine to modify it (nobody should have a reference to it anymore). This avoids the assertion failure when destroying a NMSimpleConnection with secrets that is set with nmtst_connection_assert_unchanging(). --- libnm-core/nm-connection.c | 19 ++++++++++++++++--- libnm-core/nm-core-internal.h | 1 + libnm-core/nm-simple-connection.c | 4 ++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index a2bd72b0d9..099b173659 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -1806,23 +1806,36 @@ _nmtst_connection_unchanging_secrets_updated_cb (NMConnection *connection, const nm_assert_not_reached (); } +const char _nmtst_connection_unchanging_user_data = 0; + void nmtst_connection_assert_unchanging (NMConnection *connection) { nm_assert (NM_IS_CONNECTION (connection)); + if (g_signal_handler_find (connection, + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + (gpointer) &_nmtst_connection_unchanging_user_data) != 0) { + /* avoid connecting the assertion handler multiple times. */ + return; + } + g_signal_connect (connection, NM_CONNECTION_CHANGED, G_CALLBACK (_nmtst_connection_unchanging_changed_cb), - NULL); + (gpointer) &_nmtst_connection_unchanging_user_data); g_signal_connect (connection, NM_CONNECTION_SECRETS_CLEARED, G_CALLBACK (_nmtst_connection_unchanging_changed_cb), - NULL); + (gpointer) &_nmtst_connection_unchanging_user_data); g_signal_connect (connection, NM_CONNECTION_SECRETS_UPDATED, G_CALLBACK (_nmtst_connection_unchanging_secrets_updated_cb), - NULL); + (gpointer) &_nmtst_connection_unchanging_user_data); } #endif diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index eaf29849cf..60e13937de 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -212,6 +212,7 @@ gboolean _nm_connection_ensure_normalized (NMConnection *connection, gboolean _nm_connection_remove_setting (NMConnection *connection, GType setting_type); #if NM_MORE_ASSERTS +extern const char _nmtst_connection_unchanging_user_data; void nmtst_connection_assert_unchanging (NMConnection *connection); #else static inline void diff --git a/libnm-core/nm-simple-connection.c b/libnm-core/nm-simple-connection.c index d281aa9725..f58f145f91 100644 --- a/libnm-core/nm-simple-connection.c +++ b/libnm-core/nm-simple-connection.c @@ -141,6 +141,10 @@ nm_simple_connection_new_clone (NMConnection *connection) static void dispose (GObject *object) { +#if NM_MORE_ASSERTS + g_signal_handlers_disconnect_by_data (object, (gpointer) &_nmtst_connection_unchanging_user_data); +#endif + nm_connection_clear_secrets (NM_CONNECTION (object)); G_OBJECT_CLASS (nm_simple_connection_parent_class)->dispose (object);