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