diff options
author | Thomas Haller <thaller@redhat.com> | 2019-06-21 09:51:15 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-06-26 09:53:54 +0200 |
commit | d704f02119a888bd0a43b0ce0fac7d1ddc5d2df7 (patch) | |
tree | 757af627cd77012da896f00f39e4782f57d5d63e | |
parent | b9587008fcebb5255119a457f708c7f7d1232fa1 (diff) | |
download | NetworkManager-d704f02119a888bd0a43b0ce0fac7d1ddc5d2df7.tar.gz |
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().
-rw-r--r-- | libnm-core/nm-connection.c | 19 | ||||
-rw-r--r-- | libnm-core/nm-core-internal.h | 1 | ||||
-rw-r--r-- | 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); |