From 97b681714bebc622bda3c2b6c5f463a280a003cd Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 20 Apr 2018 16:43:15 -0400 Subject: [PATCH] lib: don't emit user-added signal until list_users is completed Right now calling act_user_manager_list_users can inadvertently lead to user-added signals getting emitted before the call completes. This is not something users of the API expect. https://bugs.freedesktop.org/show_bug.cgi?id=106162 --- src/libaccountsservice/act-user-manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index 9304ea6..ade309c 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -805,90 +805,90 @@ add_user (ActUserManager *manager, { const char *object_path; g_debug ("ActUserManager: tracking user '%s'", act_user_get_user_name (user)); if (act_user_is_system_account (user)) { g_hash_table_insert (manager->priv->system_users_by_name, g_strdup (act_user_get_user_name (user)), g_object_ref (user)); } else { g_hash_table_insert (manager->priv->normal_users_by_name, g_strdup (act_user_get_user_name (user)), g_object_ref (user)); } object_path = act_user_get_object_path (user); if (object_path != NULL) { g_hash_table_replace (manager->priv->users_by_object_path, (gpointer) object_path, g_object_ref (user)); } g_signal_connect_object (user, "sessions-changed", G_CALLBACK (on_user_sessions_changed), manager, 0); g_signal_connect_object (user, "changed", G_CALLBACK (on_user_changed), manager, 0); - if (manager->priv->is_loaded) { + if (manager->priv->is_loaded && manager->priv->list_cached_users_done) { g_debug ("ActUserManager: loaded, so emitting user-added signal"); g_signal_emit (manager, signals[USER_ADDED], 0, user); } else { g_debug ("ActUserManager: not yet loaded, so not emitting user-added signal"); } } static void remove_user (ActUserManager *manager, ActUser *user) { g_debug ("ActUserManager: no longer tracking user '%s' (with object path %s)", act_user_get_user_name (user), act_user_get_object_path (user)); g_object_ref (user); g_signal_handlers_disconnect_by_func (user, on_user_changed, manager); g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager); if (act_user_get_object_path (user) != NULL) { g_hash_table_remove (manager->priv->users_by_object_path, act_user_get_object_path (user)); } if (act_user_get_user_name (user) != NULL) { g_hash_table_remove (manager->priv->normal_users_by_name, act_user_get_user_name (user)); g_hash_table_remove (manager->priv->system_users_by_name, act_user_get_user_name (user)); } - if (manager->priv->is_loaded) { + if (manager->priv->is_loaded && manager->priv->list_cached_users_done) { g_debug ("ActUserManager: loaded, so emitting user-removed signal"); g_signal_emit (manager, signals[USER_REMOVED], 0, user); } else { g_debug ("ActUserManager: not yet loaded, so not emitting user-removed signal"); } g_debug ("ActUserManager: user '%s' (with object path %s) now removed", act_user_get_user_name (user), act_user_get_object_path (user)); g_object_unref (user); } static void update_user (ActUserManager *manager, ActUser *user) { const char *username; g_debug ("ActUserManager: updating %s", describe_user (user)); username = act_user_get_user_name (user); if (g_hash_table_lookup (manager->priv->system_users_by_name, username) != NULL) { if (!act_user_is_system_account (user)) { g_debug ("ActUserManager: %s is no longer a system account, treating as normal user", describe_user (user)); g_hash_table_insert (manager->priv->normal_users_by_name, g_strdup (act_user_get_user_name (user)), g_object_ref (user)); g_hash_table_remove (manager->priv->system_users_by_name, username); g_signal_emit (manager, signals[USER_ADDED], 0, user); -- 2.16.2