summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-06-21 09:51:15 +0200
committerThomas Haller <thaller@redhat.com>2019-06-26 09:53:54 +0200
commitd704f02119a888bd0a43b0ce0fac7d1ddc5d2df7 (patch)
tree757af627cd77012da896f00f39e4782f57d5d63e
parentb9587008fcebb5255119a457f708c7f7d1232fa1 (diff)
downloadNetworkManager-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.c19
-rw-r--r--libnm-core/nm-core-internal.h1
-rw-r--r--libnm-core/nm-simple-connection.c4
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);