Blob Blame History Raw
From 30d02d642714b2417be28d430f7d4c602d38a03b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 May 2018 14:48:31 -0400
Subject: [PATCH 01/15] libgdm: drop support for serializing multiple opens

Right now libgdm tries to handle multiple simultaneous
open calls at the same time by serializing the requests
and giving them all the same connection.  It's broken,
though.

  - The pending_opens list is never populated, so we
    end up just doing multiple simultaneous open
    operations at a time anyway.
  - The finish code ends up calling
    g_task_return_error (task, NULL) instead of
    g_task_return_pointer in the non-error case.

Since the feature doesn't work, drop it for now.

https://bugzilla.gnome.org/show_bug.cgi?id=795940
---
 libgdm/gdm-client.c | 111 ++++++++++++++++----------------------------
 1 file changed, 40 insertions(+), 71 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 58ede0aab..06dfe725e 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -24,61 +24,60 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
 #include "gdm-client.h"
 #include "gdm-client-glue.h"
 #include "gdm-manager-glue.h"
 
 #define GDM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CLIENT, GdmClientPrivate))
 
 #define SESSION_DBUS_PATH      "/org/gnome/DisplayManager/Session"
 
 struct GdmClientPrivate
 {
         GdmManager         *manager;
 
         GdmUserVerifier    *user_verifier;
         GHashTable         *user_verifier_extensions;
 
         GdmGreeter         *greeter;
         GdmRemoteGreeter   *remote_greeter;
         GdmChooser         *chooser;
         GDBusConnection    *connection;
         char               *address;
 
-        GList              *pending_opens;
         char              **enabled_extensions;
 };
 
 static void     gdm_client_class_init  (GdmClientClass *klass);
 static void     gdm_client_init        (GdmClient      *client);
 static void     gdm_client_finalize    (GObject        *object);
 
 G_DEFINE_TYPE (GdmClient, gdm_client, G_TYPE_OBJECT);
 
 static gpointer client_object = NULL;
 
 GQuark
 gdm_client_error_quark (void)
 {
         static GQuark error_quark = 0;
 
         if (error_quark == 0)
                 error_quark = g_quark_from_static_string ("gdm-client");
 
         return error_quark;
 }
 
 static void
 on_got_manager (GdmManager          *manager,
                 GAsyncResult        *result,
                 GTask               *task)
 {
         GdmClient *client;
         GdmManager       *new_manager;
         GError           *error;
@@ -396,107 +395,104 @@ on_got_manager_for_reauthentication (GdmClient           *client,
         GError       *error;
 
         error = NULL;
         manager = g_task_propagate_pointer (G_TASK (result), &error);
         if (manager == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
         username = g_object_get_data (G_OBJECT (task), "username");
         gdm_manager_call_open_reauthentication_channel (client->priv->manager,
                                                         username,
                                                         cancellable,
                                                         (GAsyncReadyCallback)
                                                         on_reauthentication_channel_opened,
                                                         task);
 
 }
 
 static gboolean
 gdm_client_open_connection_sync (GdmClient      *client,
                                  GCancellable   *cancellable,
                                  GError        **error)
 {
         gboolean ret;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->manager == NULL) {
-                client->priv->manager = gdm_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-                                                                            G_DBUS_PROXY_FLAGS_NONE,
-                                                                            "org.gnome.DisplayManager",
-                                                                            "/org/gnome/DisplayManager/Manager",
-                                                                            cancellable,
-                                                                            error);
-
-                if (client->priv->manager == NULL) {
-                        goto out;
-                }
-        } else {
-                client->priv->manager = g_object_ref (client->priv->manager);
+        if (client->priv->connection != NULL) {
+                g_object_ref (client->priv->connection);
+                return TRUE;
         }
 
-        if (client->priv->connection == NULL) {
-                ret = gdm_manager_call_open_session_sync (client->priv->manager,
-                                                          &client->priv->address,
-                                                          cancellable,
-                                                          error);
+        client->priv->manager = gdm_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                                                    G_DBUS_PROXY_FLAGS_NONE,
+                                                                    "org.gnome.DisplayManager",
+                                                                    "/org/gnome/DisplayManager/Manager",
+                                                                    cancellable,
+                                                                    error);
 
-                if (!ret) {
-                        g_clear_object (&client->priv->manager);
-                        goto out;
-                }
+        if (client->priv->manager == NULL) {
+                goto out;
+        }
+
+        ret = gdm_manager_call_open_session_sync (client->priv->manager,
+                                                  &client->priv->address,
+                                                  cancellable,
+                                                  error);
 
-                g_debug ("GdmClient: connecting to address: %s", client->priv->address);
+        if (!ret) {
+                g_clear_object (&client->priv->manager);
+                goto out;
+        }
 
-                client->priv->connection = g_dbus_connection_new_for_address_sync (client->priv->address,
-                                                                                   G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
-                                                                                   NULL,
-                                                                                   cancellable,
-                                                                                   error);
+        g_debug ("GdmClient: connecting to address: %s", client->priv->address);
 
-                if (client->priv->connection == NULL) {
-                        g_clear_object (&client->priv->manager);
-                        g_clear_pointer (&client->priv->address, g_free);
-                        goto out;
-                }
+        client->priv->connection = g_dbus_connection_new_for_address_sync (client->priv->address,
+                                                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+                                                                           NULL,
+                                                                           cancellable,
+                                                                           error);
 
-                g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
-                                           (gpointer *)
-                                           &client->priv->connection);
-        } else {
-                client->priv->connection = g_object_ref (client->priv->connection);
+        if (client->priv->connection == NULL) {
+                g_clear_object (&client->priv->manager);
+                g_clear_pointer (&client->priv->address, g_free);
+                goto out;
         }
 
+        g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
+                                   (gpointer *)
+                                   &client->priv->connection);
+
  out:
         return client->priv->connection != NULL;
 }
 
 static void
 on_connected (GObject            *source_object,
               GAsyncResult       *result,
               GTask              *task)
 {
         GDBusConnection *connection;
         GError *error;
 
         error = NULL;
         connection = g_dbus_connection_new_for_address_finish (result, &error);
         if (!connection) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         g_task_return_pointer (task,
                                g_object_ref (connection),
                                (GDestroyNotify) g_object_unref);
         g_object_unref (task);
         g_object_unref (connection);
 }
 
 static void
 on_session_opened (GdmManager         *manager,
                    GAsyncResult       *result,
@@ -528,140 +524,113 @@ on_session_opened (GdmManager         *manager,
                                            on_connected,
                                            task);
         g_object_unref (client);
 }
 
 static void
 on_got_manager_for_opening_connection (GdmClient           *client,
                                        GAsyncResult        *result,
                                        GTask               *task)
 {
         GCancellable *cancellable;
         GdmManager   *manager;
         GError       *error;
 
         error = NULL;
         manager = g_task_propagate_pointer (G_TASK (result), &error);
         if (manager == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
         gdm_manager_call_open_session (client->priv->manager,
                                        cancellable,
                                        (GAsyncReadyCallback)
                                        on_session_opened,
                                        task);
 }
 
-static void
-finish_pending_opens (GdmClient *client,
-                      GError    *error)
-{
-    GList *node;
-
-    for (node = client->priv->pending_opens;
-         node != NULL;
-         node = node->next) {
-
-        GTask *task = node->data;
-
-        g_task_return_error (task, error);
-        g_object_unref (task);
-    }
-    g_clear_pointer (&client->priv->pending_opens,
-                     (GDestroyNotify) g_list_free);
-}
-
 static gboolean
 gdm_client_open_connection_finish (GdmClient      *client,
                                    GAsyncResult   *result,
                                    GError        **error)
 {
         g_autoptr(GDBusConnection) connection = NULL;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
         connection = g_task_propagate_pointer (G_TASK (result), error);
         if (connection == NULL) {
-                finish_pending_opens (client, *error);
                 return FALSE;
         }
 
         if (client->priv->connection == NULL) {
                 client->priv->connection = g_steal_pointer (&connection);
                 g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
                                            (gpointer *) &client->priv->connection);
         } else if (client->priv->connection == connection) {
                 connection = NULL;
         }
 
-        finish_pending_opens (client, NULL);
         return TRUE;
 }
 
 static void
 gdm_client_open_connection (GdmClient           *client,
                             GCancellable        *cancellable,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
 {
         GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
         task = g_task_new (G_OBJECT (client),
                            cancellable,
                            callback,
                            user_data);
 
         if (client->priv->connection != NULL) {
             g_task_return_pointer (task,
                                    g_object_ref (client->priv->connection),
                                    (GDestroyNotify) g_object_unref);
             g_object_unref (task);
             return;
         }
 
-        if (client->priv->pending_opens == NULL) {
-            get_manager (client,
-                         cancellable,
-                         (GAsyncReadyCallback)
-                         on_got_manager_for_opening_connection,
-                         task);
-        } else {
-                client->priv->pending_opens = g_list_prepend (client->priv->pending_opens,
-                                                              task);
-        }
-
+        get_manager (client,
+                     cancellable,
+                     (GAsyncReadyCallback)
+                     on_got_manager_for_opening_connection,
+                     task);
 }
 
 /**
  * gdm_client_open_reauthentication_channel_sync:
  * @client: a #GdmClient
  * @username: user to reauthenticate
  * @cancellable: a #GCancellable
  * @error: a #GError
  *
  * Gets a #GdmUserVerifier object that can be used to
  * reauthenticate an already logged in user. Free with
  * g_object_unref to close reauthentication channel.
  *
  * Returns: (transfer full): #GdmUserVerifier or %NULL if @username is not
  * already logged in.
  */
 GdmUserVerifier *
 gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                const char    *username,
                                                GCancellable  *cancellable,
                                                GError       **error)
 {
         GDBusConnection *connection;
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
         char            *address;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
         if (client->priv->manager == NULL) {
-- 
2.25.1