Blob Blame Raw
From f674b04a79a7974a697ad69a997bec21742d3299 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
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