From 889561310b794f0443dc5c520b09151fe4b260ec Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 27 Sep 2017 10:43:33 -0400 Subject: [PATCH 03/13] lib: another leak fix If a user gets removed from account service before it's fully loaded, then we neglect to drop its reference on the new_users lists. This commit fixes that. --- src/libaccountsservice/act-user-manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index c8d0443..ac06e24 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -1108,71 +1108,77 @@ add_new_user_for_object_path (const char *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; 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; 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); } - manager->priv->new_users = g_slist_remove (manager->priv->new_users, user); + 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); if (!console_kit_manager_call_get_current_session_finish (proxy, &session_id, result, &error)) { if (error != NULL) { g_debug ("Failed to identify the current session: %s", error->message); g_error_free (error); } else { g_debug ("Failed to identify the current session"); } unload_seat (manager); goto out; } manager->priv->seat.session_id = session_id; -- 2.14.1