From e7ad15bc5ca5649f719679c3791244eccba0f057 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Mon, 6 Nov 2023 13:00:29 +0300 Subject: [PATCH 6/8] ag-account: do not emit misleading enabled signals on account services Something must have changed in the internals of GHashTable, so that now the keys happen to be ordered in such a way that broke a libaccounts-qt test in Ubuntu 22.04 [1]. The failure has been traced back to libaccounts-glib, and happens when the enabled properties on an account and on one of its services are changed in such a way that the overall service status should remain disabled, yet two enabled signals (first one with value "enabled", second "disabled") are emitted on the account service. While the end result is correct, the two signals would be better not be emitted at all, since the account service enabledness never actually changed. To fix this, instead of emitting the AgAccount::enabled signals while we iterate the changes, we delay their emission until the end of the update loop, so that the AgAccountService will already have the updated information on the enabledness status and won't emit its enabled signal. [1]: https://gitlab.com/accounts-sso/libaccounts-qt/-/merge_requests/18#note_1138904460 --- libaccounts-glib/ag-account.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/libaccounts-glib/ag-account.c b/libaccounts-glib/ag-account.c index 7e67ba7..ab19ba2 100644 --- a/libaccounts-glib/ag-account.c +++ b/libaccounts-glib/ag-account.c @@ -223,6 +223,11 @@ typedef struct { gpointer user_data; } AsyncReadyCbWrapperData; +typedef struct { + gchar *service_name; + gboolean enabled; +} EnabledSignalParams; + #define AG_ITER_STAGE_UNSET 0 #define AG_ITER_STAGE_ACCOUNT 1 #define AG_ITER_STAGE_SERVICE 2 @@ -584,6 +589,7 @@ update_settings (AgAccount *account, GHashTable *services) AgServiceChanges *sc; gchar *service_name; GList *watch_list = NULL; + GSList *enabled_signals = NULL; g_hash_table_iter_init (&iter, services); while (g_hash_table_iter_next (&iter, @@ -641,10 +647,12 @@ update_settings (AgAccount *account, GHashTable *services) { priv->enabled = value ? g_variant_get_boolean (value) : FALSE; - g_signal_emit (account, signals[ENABLED], 0, - NULL, priv->enabled); g_object_notify_by_pspec ((GObject *)account, properties[PROP_ENABLED]); + EnabledSignalParams *params = g_new (EnabledSignalParams, 1); + params->service_name = NULL; + params->enabled = priv->enabled; + enabled_signals = g_slist_prepend (enabled_signals, params); continue; } } @@ -665,12 +673,24 @@ update_settings (AgAccount *account, GHashTable *services) { gboolean enabled = value ? g_variant_get_boolean (value) : FALSE; - g_signal_emit (account, signals[ENABLED], 0, - service_name, enabled); + EnabledSignalParams *params = g_new (EnabledSignalParams, 1); + params->service_name = service_name; + params->enabled = enabled; + enabled_signals = g_slist_prepend (enabled_signals, params); } } } + /* Emit all enabled signals */ + while (enabled_signals) + { + EnabledSignalParams *params = enabled_signals->data; + g_signal_emit (account, signals[ENABLED], 0, + params->service_name, params->enabled); + g_free (params); + enabled_signals = g_slist_delete_link (enabled_signals, enabled_signals); + } + /* Invoke all watches * While whatches are running, let the receivers retrieve the changes * table with _ag_account_get_service_changes(): set it into the -- 2.44.0