From f674b04a79a7974a697ad69a997bec21742d3299 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 4 Oct 2017 11:21:44 -0400 Subject: [PATCH 12/13] lib: don't track user-added/user-removed until we get initial list There's no reason to process user-added and user-removed signals until we have our starting list. Those signals are supposed to be a delta off that list anyway. --- src/libaccountsservice/act-user-manager.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index c8a0e20..11049e0 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -173,60 +173,61 @@ typedef struct char *object_path; char *description; } ActUserManagerFetchUserRequest; struct ActUserManagerPrivate { GHashTable *normal_users_by_name; GHashTable *system_users_by_name; GHashTable *users_by_object_path; GHashTable *sessions; GDBusConnection *connection; AccountsAccounts *accounts_proxy; ConsoleKitManager *ck_manager_proxy; ActUserManagerSeat seat; GSList *new_sessions; GSList *new_users; GSList *new_users_inhibiting_load; GSList *fetch_user_requests; GSList *exclude_usernames; GSList *include_usernames; guint load_id; gboolean is_loaded; gboolean has_multiple_users; gboolean getting_sessions; gboolean listing_cached_users; + gboolean list_cached_users_done; }; enum { PROP_0, PROP_INCLUDE_USERNAMES_LIST, PROP_EXCLUDE_USERNAMES_LIST, PROP_IS_LOADED, PROP_HAS_MULTIPLE_USERS }; enum { USER_ADDED, USER_REMOVED, USER_IS_LOGGED_IN_CHANGED, USER_CHANGED, LAST_SIGNAL }; static guint signals [LAST_SIGNAL] = { 0, }; static void act_user_manager_class_init (ActUserManagerClass *klass); static void act_user_manager_init (ActUserManager *user_manager); static void act_user_manager_finalize (GObject *object); static gboolean ensure_accounts_proxy (ActUserManager *manager); static gboolean load_seat_incrementally (ActUserManager *manager); static void unload_seat (ActUserManager *manager); static void load_users (ActUserManager *manager); static void act_user_manager_queue_load (ActUserManager *manager); static void queue_load_seat_and_users (ActUserManager *manager); @@ -1075,80 +1076,92 @@ add_new_user_for_object_path (const char *object_path, if (user != NULL) { g_debug ("ActUserManager: tracking existing %s with object path %s", describe_user (user), object_path); return user; } user = find_new_user_with_object_path (manager, object_path); if (user != NULL) { g_debug ("ActUserManager: tracking existing (but very recently added) %s with object path %s", describe_user (user), object_path); return user; } g_debug ("ActUserManager: tracking new user with object path %s", object_path); user = create_new_user (manager); _act_user_update_from_object_path (user, object_path); return user; } static void on_new_user_in_accounts_service (GDBusProxy *proxy, const char *object_path, gpointer user_data) { ActUserManager *manager = ACT_USER_MANAGER (user_data); ActUser *user; + /* Only track user changes if the user has requested a list + * of users */ + if (!manager->priv->list_cached_users_done) { + return; + } + if (!manager->priv->is_loaded) { g_debug ("ActUserManager: ignoring new user in accounts service with object path %s since not loaded yet", object_path); return; } g_debug ("ActUserManager: new user in accounts service with object path %s", object_path); user = add_new_user_for_object_path (object_path, manager); g_object_unref (user); } static void on_user_removed_in_accounts_service (GDBusProxy *proxy, const char *object_path, gpointer user_data) { ActUserManager *manager = ACT_USER_MANAGER (user_data); ActUser *user; GSList *node; + /* Only track user changes if the user has requested a list + * of users */ + if (!manager->priv->list_cached_users_done) { + return; + } + user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); if (user == NULL) { g_debug ("ActUserManager: ignoring untracked user %s", object_path); return; } else { g_debug ("ActUserManager: tracked user %s removed from accounts service", object_path); } node = g_slist_find (manager->priv->new_users, user); if (node != NULL) { g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager); g_object_unref (user); manager->priv->new_users = g_slist_delete_link (manager->priv->new_users, node); } remove_user (manager, user); } static void on_get_current_session_finished (GObject *object, GAsyncResult *result, gpointer data) { ConsoleKitManager *proxy = CONSOLE_KIT_MANAGER (object); ActUserManager *manager = data; GError *error = NULL; char *session_id; g_assert (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID); @@ -1532,60 +1545,61 @@ load_included_usernames (ActUserManager *manager) { GSList *l; /* Add users who are specifically included */ for (l = manager->priv->include_usernames; l != NULL; l = l->next) { ActUser *user; g_debug ("ActUserManager: Adding included user %s", (char *)l->data); /* * The call to act_user_manager_get_user will add the user if it is * valid and not already in the hash. */ user = act_user_manager_get_user (manager, l->data); if (user == NULL) { g_debug ("ActUserManager: unable to lookup user '%s'", (char *)l->data); } } } static void on_list_cached_users_finished (GObject *object, GAsyncResult *result, gpointer data) { AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object); ActUserManager *manager = data; gchar **user_paths; GError *error = NULL; manager->priv->listing_cached_users = FALSE; + manager->priv->list_cached_users_done = TRUE; if (!accounts_accounts_call_list_cached_users_finish (proxy, &user_paths, result, &error)) { g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); g_error_free (error); g_object_unref (manager->priv->accounts_proxy); manager->priv->accounts_proxy = NULL; g_debug ("ActUserManager: unrefing manager owned by failed ListCachedUsers call"); g_object_unref (manager); return; } load_user_paths (manager, (const char * const *) user_paths); g_strfreev (user_paths); load_included_usernames (manager); g_debug ("ActUserManager: unrefing manager owned by finished ListCachedUsers call"); g_object_unref (manager); } static void on_get_x11_display_finished (GObject *object, GAsyncResult *result, gpointer data) { ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object); ActUserManagerNewSession *new_session = data; GError *error = NULL; -- 2.14.1