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().
This commit is contained in:
Thomas Haller
2019-06-21 09:51:15 +02:00
parent b9587008fc
commit d704f02119
3 changed files with 21 additions and 3 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);