From 9568eccdaa3c9cfcd129c4e7a53584ea5866772b Mon Sep 17 00:00:00 2001
From: Robert Ancell <robert.ancell@canonical.com>
Date: Tue, 5 Dec 2017 14:20:41 +1300
Subject: [PATCH 01/19] Generate autocleanup definitions in libgdm

---
 libgdm/Makefile.am  | 2 ++
 libgdm/gdm-client.h | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/libgdm/Makefile.am b/libgdm/Makefile.am
index 99ada9aa..2f7d7b61 100644
--- a/libgdm/Makefile.am
+++ b/libgdm/Makefile.am
@@ -12,6 +12,7 @@ gdm-manager-glue.c gdm-manager-glue.h : $(top_srcdir)/daemon/gdm-manager.xml Mak
 		--c-namespace Gdm				\
 		--interface-prefix=org.gnome.DisplayManager		\
 		--generate-c-code=gdm-manager-glue			\
+		--c-generate-autocleanup=all				\
 		--annotate "org.gnome.DisplayManager.Manager"		\
 		           "org.gtk.GDBus.C.Name" Manager		\
 		$(top_srcdir)/daemon/gdm-manager.xml
@@ -21,6 +22,7 @@ gdm-client-glue.c gdm-client-glue.h : $(top_srcdir)/daemon/gdm-session.xml Makef
 		--c-namespace Gdm				\
 		--interface-prefix=org.gnome.DisplayManager		\
 		--generate-c-code=gdm-client-glue			\
+		--c-generate-autocleanup=all				\
 		--annotate "org.gnome.DisplayManager.UserVerifier"	\
 		           "org.gtk.GDBus.C.Name" UserVerifier	\
 		--annotate "org.gnome.DisplayManager.Greeter"		\
diff --git a/libgdm/gdm-client.h b/libgdm/gdm-client.h
index 1ae3d39e..8718a2ef 100644
--- a/libgdm/gdm-client.h
+++ b/libgdm/gdm-client.h
@@ -122,6 +122,10 @@ GdmChooser        *gdm_client_get_chooser_sync          (GdmClient *client,
                                                          GCancellable     *cancellable,
                                                          GError          **error);
 
+#if GLIB_CHECK_VERSION(2, 44, 0)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdmClient, g_object_unref)
+#endif
+
 G_END_DECLS
 
 #endif /* __GDM_CLIENT_H */
-- 
2.32.0


From e9e60e2a6a4cdeb30e7b7b850a57ef2f9dabd947 Mon Sep 17 00:00:00 2001
From: Robert Ancell <robert.ancell@canonical.com>
Date: Mon, 4 Dec 2017 16:15:59 +1300
Subject: [PATCH 02/19] Replace deprecated GSimpleAsyncResult with GTask

https://bugzilla.gnome.org/show_bug.cgi?id=783082
---
 libgdm/gdm-client.c | 531 ++++++++++++++++++++------------------------
 1 file changed, 235 insertions(+), 296 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 6fd55bd0..bcae8ba2 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -77,13 +77,13 @@ gdm_client_error_quark (void)
 static void
 on_got_manager (GdmManager          *manager,
                 GAsyncResult        *result,
-                GSimpleAsyncResult  *operation_result)
+                GTask               *task)
 {
         GdmClient *client;
         GdmManager       *new_manager;
         GError           *error;
 
-        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
 
         error = NULL;
         new_manager = gdm_manager_proxy_new_finish (result, &error);
@@ -99,16 +99,14 @@ on_got_manager (GdmManager          *manager,
         }
 
         if (error != NULL) {
-                g_simple_async_result_take_error (operation_result, error);
+                g_task_return_error (task, error);
         } else {
-                g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                           g_object_ref (client->priv->manager),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->manager),
+                                       (GDestroyNotify) g_object_unref);
         }
 
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        g_object_unref (task);
         g_object_unref (client);
 }
 
@@ -118,21 +116,18 @@ get_manager (GdmClient           *client,
              GAsyncReadyCallback  callback,
              gpointer             user_data)
 {
-        GSimpleAsyncResult *result;
+        GTask *task;
 
-        result = g_simple_async_result_new (G_OBJECT (client),
-                                            callback,
-                                            user_data,
-                                            get_manager);
-        g_simple_async_result_set_check_cancellable (result, cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->manager != NULL) {
-                g_simple_async_result_set_op_res_gpointer (result,
-                                                           g_object_ref (client->priv->manager),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
-                g_simple_async_result_complete_in_idle (result);
-                g_object_unref (result);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->manager),
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -143,20 +138,47 @@ get_manager (GdmClient           *client,
                                        cancellable,
                                        (GAsyncReadyCallback)
                                        on_got_manager,
-                                       result);
+                                       task);
+}
+
+typedef struct {
+        GTask           *task;
+        GdmUserVerifier *user_verifier;
+} UserVerifierData;
+
+static UserVerifierData *
+user_verifier_data_new (GTask *task, GdmUserVerifier *user_verifier)
+{
+        UserVerifierData *data;
+
+        data = g_slice_new (UserVerifierData);
+        data->task = g_object_ref (task);
+        data->user_verifier = g_object_ref (user_verifier);
+
+        return data;
+}
+
+static void
+user_verifier_data_free (UserVerifierData *data)
+{
+        g_object_unref (data->task);
+        g_object_unref (data->user_verifier);
+        g_slice_free (UserVerifierData, data);
 }
 
 static void
 complete_user_verifier_proxy_operation (GdmClient          *client,
-                                        GSimpleAsyncResult *operation_result)
+                                        UserVerifierData   *data)
 {
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        g_task_return_pointer (data->task,
+                               g_object_ref (data->user_verifier),
+                               (GDestroyNotify) g_object_unref);
+        user_verifier_data_free (data);
 }
 
 static void
 maybe_complete_user_verifier_proxy_operation (GdmClient          *client,
-                                              GSimpleAsyncResult *operation_result)
+                                              UserVerifierData   *data)
 {
         GHashTableIter iter;
         gpointer key, value;
@@ -169,19 +191,19 @@ maybe_complete_user_verifier_proxy_operation (GdmClient          *client,
                 }
         }
 
-        complete_user_verifier_proxy_operation (client, operation_result);
+        complete_user_verifier_proxy_operation (client, data);
 }
 
 static void
 on_user_verifier_choice_list_proxy_created (GObject            *source,
                                             GAsyncResult       *result,
-                                            GSimpleAsyncResult *operation_result)
+                                            UserVerifierData   *data)
 {
         GdmClient                 *client;
         GdmUserVerifierChoiceList *choice_list;
         GError                    *error = NULL;
 
-        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
 
         choice_list = gdm_user_verifier_choice_list_proxy_new_finish (result, &error);
 
@@ -193,13 +215,13 @@ on_user_verifier_choice_list_proxy_created (GObject            *source,
                 g_hash_table_replace (client->priv->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name, choice_list);
         }
 
-        maybe_complete_user_verifier_proxy_operation (client, operation_result);
+        maybe_complete_user_verifier_proxy_operation (client, data);
 }
 
 static void
 on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
                                      GAsyncResult       *result,
-                                     GSimpleAsyncResult *operation_result)
+                                     UserVerifierData   *data)
 {
         GdmClient *client;
         GCancellable *cancellable;
@@ -207,8 +229,8 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
         GError    *error = NULL;
         size_t     i;
 
-        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
+        cancellable = g_task_get_cancellable (data->task);
 
         gdm_user_verifier_call_enable_extensions_finish (user_verifier, result, &error);
 
@@ -216,7 +238,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
                 g_debug ("Couldn't enable user verifier extensions: %s",
                          error->message);
                 g_clear_error (&error);
-                complete_user_verifier_proxy_operation (client, operation_result);
+                complete_user_verifier_proxy_operation (client, data);
                 return;
         }
 
@@ -236,7 +258,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
                                                                  cancellable,
                                                                  (GAsyncReadyCallback)
                                                                  on_user_verifier_choice_list_proxy_created,
-                                                                 operation_result);
+                                                                 data);
                 } else {
                         g_debug ("User verifier extension %s is unsupported", client->priv->enabled_extensions[i]);
                         g_hash_table_remove (client->priv->user_verifier_extensions,
@@ -246,7 +268,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
 
         if (g_hash_table_size (client->priv->user_verifier_extensions) == 0) {
                 g_debug ("No supported user verifier extensions");
-                complete_user_verifier_proxy_operation (client, operation_result);
+                complete_user_verifier_proxy_operation (client, data);
         }
 
 }
@@ -263,7 +285,7 @@ free_interface_skeleton (GDBusInterfaceSkeleton *interface)
 static void
 on_user_verifier_proxy_created (GObject            *source,
                                 GAsyncResult       *result,
-                                GSimpleAsyncResult *operation_result)
+                                GTask              *task)
 {
         GdmClient       *self;
         GdmUserVerifier *user_verifier;
@@ -272,24 +294,20 @@ on_user_verifier_proxy_created (GObject            *source,
 
         user_verifier = gdm_user_verifier_proxy_new_finish (result, &error);
         if (user_verifier == NULL) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
         g_debug ("UserVerifier %p created", user_verifier);
 
-        g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                   user_verifier,
-                                                   (GDestroyNotify)
-                                                   g_object_unref);
-
-        self = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+        self = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
         if (self->priv->enabled_extensions == NULL) {
                 g_debug ("no enabled extensions");
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_pointer (task,
+                                       user_verifier,
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -298,21 +316,21 @@ on_user_verifier_proxy_created (GObject            *source,
                                                                       NULL,
                                                                       (GDestroyNotify)
                                                                       free_interface_skeleton);
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_user_verifier_call_enable_extensions (user_verifier,
                                                   (const char * const *)
                                                   self->priv->enabled_extensions,
                                                   cancellable,
                                                   (GAsyncReadyCallback)
                                                   on_user_verifier_extensions_enabled,
-                                                  operation_result);
-
+                                                  user_verifier_data_new (task, user_verifier));
+        g_object_unref (user_verifier);
 }
 
 static void
 on_reauthentication_channel_connected (GObject            *source_object,
                                        GAsyncResult       *result,
-                                       GSimpleAsyncResult *operation_result)
+                                       GTask              *task)
 {
         GDBusConnection *connection;
         GCancellable *cancellable;
@@ -321,13 +339,12 @@ on_reauthentication_channel_connected (GObject            *source_object,
         error = NULL;
         connection = g_dbus_connection_new_for_address_finish (result, &error);
         if (!connection) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_user_verifier_proxy_new (connection,
                                      G_DBUS_PROXY_FLAGS_NONE,
                                      NULL,
@@ -335,14 +352,14 @@ on_reauthentication_channel_connected (GObject            *source_object,
                                      cancellable,
                                      (GAsyncReadyCallback)
                                      on_user_verifier_proxy_created,
-                                     operation_result);
+                                     task);
         g_object_unref (connection);
 }
 
 static void
 on_reauthentication_channel_opened (GdmManager         *manager,
                                     GAsyncResult       *result,
-                                    GSimpleAsyncResult *operation_result)
+                                    GTask              *task)
 {
         GCancellable *cancellable;
         char         *address;
@@ -353,48 +370,45 @@ on_reauthentication_channel_opened (GdmManager         *manager,
                                                                     &address,
                                                                     result,
                                                                     &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         g_dbus_connection_new_for_address (address,
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL,
                                            cancellable,
                                            (GAsyncReadyCallback)
                                            on_reauthentication_channel_connected,
-                                           operation_result);
+                                           task);
 }
 
 static void
 on_got_manager_for_reauthentication (GdmClient           *client,
                                      GAsyncResult        *result,
-                                     GSimpleAsyncResult  *operation_result)
+                                     GTask               *task)
 {
         GCancellable *cancellable;
         char         *username;
         GError       *error;
 
         error = NULL;
-        if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                   &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+        if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
-        username = g_object_get_data (G_OBJECT (operation_result), "username");
+        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,
-                                                        operation_result);
+                                                        task);
 
 }
 
@@ -457,7 +471,7 @@ gdm_client_open_connection_sync (GdmClient      *client,
 static void
 on_connected (GObject            *source_object,
               GAsyncResult       *result,
-              GSimpleAsyncResult *operation_result)
+              GTask              *task)
 {
         GDBusConnection *connection;
         GError *error;
@@ -465,78 +479,72 @@ on_connected (GObject            *source_object,
         error = NULL;
         connection = g_dbus_connection_new_for_address_finish (result, &error);
         if (!connection) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                   g_object_ref (connection),
-                                                   (GDestroyNotify)
-                                                   g_object_unref);
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        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,
-                   GSimpleAsyncResult *operation_result)
+                   GTask              *task)
 {
         GdmClient *client;
         GCancellable     *cancellable;
         GError           *error;
 
-        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+        client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
 
         error = NULL;
         if (!gdm_manager_call_open_session_finish (manager,
                                                    &client->priv->address,
                                                    result,
                                                    &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 g_object_unref (client);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         g_dbus_connection_new_for_address (client->priv->address,
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL,
                                            cancellable,
                                            (GAsyncReadyCallback)
                                            on_connected,
-                                           operation_result);
+                                           task);
         g_object_unref (client);
 }
 
 static void
 on_got_manager_for_opening_connection (GdmClient           *client,
                                        GAsyncResult        *result,
-                                       GSimpleAsyncResult  *operation_result)
+                                       GTask               *task)
 {
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
-        if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                   &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+        if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_manager_call_open_session (client->priv->manager,
                                        cancellable,
                                        (GAsyncReadyCallback)
                                        on_session_opened,
-                                       operation_result);
+                                       task);
 }
 
 static void
@@ -549,11 +557,10 @@ finish_pending_opens (GdmClient *client,
          node != NULL;
          node = node->next) {
 
-        GSimpleAsyncResult *pending_result = node->data;
+        GTask *task = node->data;
 
-        g_simple_async_result_set_from_error (pending_result, error);
-        g_simple_async_result_complete_in_idle (pending_result);
-        g_object_unref (pending_result);
+        g_task_return_error (task, error);
+        g_object_unref (task);
     }
     g_clear_pointer (&client->priv->pending_opens,
                      (GDestroyNotify) g_list_free);
@@ -564,16 +571,18 @@ 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);
 
-        if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                   error)) {
-            finish_pending_opens (client, *error);
-            return 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_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+                client->priv->connection = g_steal_pointer (&connection);
         }
 
         finish_pending_opens (client, NULL);
@@ -586,27 +595,20 @@ gdm_client_open_connection (GdmClient           *client,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_open_connection);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->connection != NULL) {
-            g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                       g_object_ref (client->priv->connection),
-                                                       (GDestroyNotify)
-                                                       g_object_unref);
-            g_simple_async_result_complete_in_idle (operation_result);
-            g_object_unref (operation_result);
+            g_task_return_pointer (task,
+                                   g_object_ref (client->priv->connection),
+                                   (GDestroyNotify) g_object_unref);
+            g_object_unref (task);
             return;
         }
 
@@ -615,10 +617,10 @@ gdm_client_open_connection (GdmClient           *client,
                          cancellable,
                          (GAsyncReadyCallback)
                          on_got_manager_for_opening_connection,
-                         operation_result);
+                         task);
         } else {
                 client->priv->pending_opens = g_list_prepend (client->priv->pending_opens,
-                                                              operation_result);
+                                                              task);
         }
 
 }
@@ -730,20 +732,16 @@ gdm_client_open_reauthentication_channel (GdmClient           *client,
                                           GAsyncReadyCallback  callback,
                                           gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_open_reauthentication_channel);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
-        g_object_set_data_full (G_OBJECT (operation_result),
+        g_object_set_data_full (G_OBJECT (task),
                                 "username",
                                 g_strdup (username),
                                 (GDestroyNotify)
@@ -753,7 +751,7 @@ gdm_client_open_reauthentication_channel (GdmClient           *client,
                      cancellable,
                      (GAsyncReadyCallback)
                      on_got_manager_for_reauthentication,
-                     operation_result);
+                     task);
 }
 
 /**
@@ -772,18 +770,9 @@ gdm_client_open_reauthentication_channel_finish (GdmClient       *client,
                                                  GAsyncResult    *result,
                                                  GError         **error)
 {
-        GdmUserVerifier *user_verifier;
-
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                   error)) {
-                return NULL;
-        }
-
-        user_verifier = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
-
-        return g_object_ref (user_verifier);
+        return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 /**
@@ -870,20 +859,19 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
 static void
 on_connection_opened_for_user_verifier (GdmClient          *client,
                                         GAsyncResult       *result,
-                                        GSimpleAsyncResult *operation_result)
+                                        GTask              *task)
 {
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
         if (!gdm_client_open_connection_finish (client, result, &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_user_verifier_proxy_new (client->priv->connection,
                                      G_DBUS_PROXY_FLAGS_NONE,
                                      NULL,
@@ -891,7 +879,7 @@ on_connection_opened_for_user_verifier (GdmClient          *client,
                                      cancellable,
                                      (GAsyncReadyCallback)
                                      on_user_verifier_proxy_created,
-                                     operation_result);
+                                     task);
 }
 
 /**
@@ -910,27 +898,20 @@ gdm_client_get_user_verifier (GdmClient           *client,
                               GAsyncReadyCallback  callback,
                               gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_get_user_verifier);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->user_verifier != NULL) {
-                g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                           g_object_ref (client->priv->user_verifier),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->user_verifier),
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -938,7 +919,7 @@ gdm_client_get_user_verifier (GdmClient           *client,
                                     cancellable,
                                     (GAsyncReadyCallback)
                                     on_connection_opened_for_user_verifier,
-                                    operation_result);
+                                    task);
 }
 
 /**
@@ -961,14 +942,12 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->user_verifier != NULL) {
+        if (client->priv->user_verifier != NULL)
                 return g_object_ref (client->priv->user_verifier);
-        } else if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                          error)) {
-                return NULL;
-        }
 
-        user_verifier = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+        user_verifier = g_task_propagate_pointer (G_TASK (result), error);
+        if (user_verifier == NULL)
+                return NULL;
 
         client->priv->user_verifier = user_verifier;
 
@@ -986,7 +965,7 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
                            g_clear_object,
                            &client->priv->manager);
 
-        return g_object_ref (user_verifier);
+        return user_verifier;
 }
 
 /**
@@ -1032,25 +1011,22 @@ query_for_timed_login_requested_signal (GdmGreeter *greeter)
 static void
 on_greeter_proxy_created (GObject            *source,
                           GAsyncResult       *result,
-                          GSimpleAsyncResult *operation_result)
+                          GTask              *task)
 {
         GdmGreeter   *greeter;
         GError       *error = NULL;
 
         greeter = gdm_greeter_proxy_new_finish (result, &error);
         if (greeter == NULL) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                   greeter,
-                                                   (GDestroyNotify)
-                                                   g_object_unref);
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        g_task_return_pointer (task,
+                               greeter,
+                               (GDestroyNotify) g_object_unref);
+        g_object_unref (task);
 
         query_for_timed_login_requested_signal (greeter);
 }
@@ -1058,20 +1034,19 @@ on_greeter_proxy_created (GObject            *source,
 static void
 on_connection_opened_for_greeter (GdmClient          *client,
                                   GAsyncResult       *result,
-                                  GSimpleAsyncResult *operation_result)
+                                  GTask              *task)
 {
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
         if (!gdm_client_open_connection_finish (client, result, &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_greeter_proxy_new (client->priv->connection,
                                G_DBUS_PROXY_FLAGS_NONE,
                                NULL,
@@ -1079,7 +1054,7 @@ on_connection_opened_for_greeter (GdmClient          *client,
                                cancellable,
                                (GAsyncReadyCallback)
                                on_greeter_proxy_created,
-                               operation_result);
+                               task);
 }
 
 /**
@@ -1098,27 +1073,20 @@ gdm_client_get_greeter (GdmClient           *client,
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_get_greeter);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->greeter != NULL) {
-                g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                           g_object_ref (client->priv->greeter),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->greeter),
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -1126,7 +1094,7 @@ gdm_client_get_greeter (GdmClient           *client,
                                     cancellable,
                                     (GAsyncReadyCallback)
                                     on_connection_opened_for_greeter,
-                                    operation_result);
+                                    task);
 }
 
 /**
@@ -1149,14 +1117,12 @@ gdm_client_get_greeter_finish (GdmClient       *client,
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->greeter != NULL) {
+        if (client->priv->greeter != NULL)
                 return g_object_ref (client->priv->greeter);
-        } else if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                          error)) {
-                return NULL;
-        }
 
-        greeter = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+        greeter = g_task_propagate_pointer (G_TASK (result), error);
+        if (greeter == NULL)
+                return NULL;
 
         client->priv->greeter = greeter;
 
@@ -1174,7 +1140,7 @@ gdm_client_get_greeter_finish (GdmClient       *client,
                            g_clear_object,
                            &client->priv->manager);
 
-        return g_object_ref (greeter);
+        return greeter;
 }
 
 /**
@@ -1232,44 +1198,40 @@ gdm_client_get_greeter_sync (GdmClient     *client,
 static void
 on_remote_greeter_proxy_created (GObject            *object,
                                  GAsyncResult       *result,
-                                 GSimpleAsyncResult *operation_result)
+                                 GTask              *task)
 {
         GdmRemoteGreeter *remote_greeter;
         GError           *error = NULL;
 
         remote_greeter = gdm_remote_greeter_proxy_new_finish (result, &error);
         if (remote_greeter == NULL) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                   remote_greeter,
-                                                   (GDestroyNotify)
-                                                   g_object_unref);
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        g_task_return_pointer (task,
+                               remote_greeter,
+                               (GDestroyNotify) g_object_unref);
+        g_object_unref (task);
 }
 
 static void
 on_connection_opened_for_remote_greeter (GdmClient          *client,
                                          GAsyncResult       *result,
-                                         GSimpleAsyncResult *operation_result)
+                                         GTask              *task)
 {
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
         if (!gdm_client_open_connection_finish (client, result, &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_remote_greeter_proxy_new (client->priv->connection,
                                       G_DBUS_PROXY_FLAGS_NONE,
                                       NULL,
@@ -1277,7 +1239,7 @@ on_connection_opened_for_remote_greeter (GdmClient          *client,
                                       cancellable,
                                       (GAsyncReadyCallback)
                                       on_remote_greeter_proxy_created,
-                                      operation_result);
+                                      task);
 }
 
 /**
@@ -1296,27 +1258,20 @@ gdm_client_get_remote_greeter (GdmClient           *client,
                                GAsyncReadyCallback  callback,
                                gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_get_remote_greeter);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->remote_greeter != NULL) {
-                g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                           g_object_ref (client->priv->remote_greeter),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->remote_greeter),
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -1324,7 +1279,7 @@ gdm_client_get_remote_greeter (GdmClient           *client,
                                     cancellable,
                                     (GAsyncReadyCallback)
                                     on_connection_opened_for_remote_greeter,
-                                    operation_result);
+                                    task);
 }
 
 /**
@@ -1347,14 +1302,12 @@ gdm_client_get_remote_greeter_finish (GdmClient     *client,
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->remote_greeter != NULL) {
+        if (client->priv->remote_greeter != NULL)
                 return g_object_ref (client->priv->remote_greeter);
-        } else if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                          error)) {
-                return NULL;
-        }
 
-        remote_greeter = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+        remote_greeter = g_task_propagate_pointer (G_TASK (result), error);
+        if (remote_greeter == NULL)
+                return NULL;
 
         client->priv->remote_greeter = remote_greeter;
 
@@ -1372,7 +1325,7 @@ gdm_client_get_remote_greeter_finish (GdmClient     *client,
                            g_clear_object,
                            &client->priv->manager);
 
-        return g_object_ref (remote_greeter);
+        return remote_greeter;
 }
 
 /**
@@ -1427,44 +1380,40 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
 static void
 on_chooser_proxy_created (GObject            *source,
                           GAsyncResult       *result,
-                          GSimpleAsyncResult *operation_result)
+                          GTask              *task)
 {
         GdmChooser   *chooser;
         GError       *error = NULL;
 
         chooser = gdm_chooser_proxy_new_finish (result, &error);
         if (chooser == NULL) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                   chooser,
-                                                   (GDestroyNotify)
-                                                   g_object_unref);
-        g_simple_async_result_complete_in_idle (operation_result);
-        g_object_unref (operation_result);
+        g_task_return_pointer (task,
+                               chooser,
+                               (GDestroyNotify) g_object_unref);
+        g_object_unref (task);
 }
 
 static void
 on_connection_opened_for_chooser (GdmClient          *client,
                                   GAsyncResult       *result,
-                                  GSimpleAsyncResult *operation_result)
+                                  GTask              *task)
 {
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
         if (!gdm_client_open_connection_finish (client, result, &error)) {
-                g_simple_async_result_take_error (operation_result, error);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_error (task, error);
+                g_object_unref (task);
                 return;
         }
 
-        cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+        cancellable = g_task_get_cancellable (task);
         gdm_chooser_proxy_new (client->priv->connection,
                                G_DBUS_PROXY_FLAGS_NONE,
                                NULL,
@@ -1472,7 +1421,7 @@ on_connection_opened_for_chooser (GdmClient          *client,
                                cancellable,
                                (GAsyncReadyCallback)
                                on_chooser_proxy_created,
-                               operation_result);
+                               task);
 }
 
 /**
@@ -1491,27 +1440,20 @@ gdm_client_get_chooser (GdmClient           *client,
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
 {
-        GSimpleAsyncResult *operation_result;
+        GTask *task;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
-        operation_result = g_simple_async_result_new (G_OBJECT (client),
-                                                      callback,
-                                                      user_data,
-                                                      gdm_client_get_chooser);
-        g_simple_async_result_set_check_cancellable (operation_result, cancellable);
-
-        g_object_set_data (G_OBJECT (operation_result),
-                           "cancellable",
-                           cancellable);
+        task = g_task_new (G_OBJECT (client),
+                           cancellable,
+                           callback,
+                           user_data);
 
         if (client->priv->chooser != NULL) {
-                g_simple_async_result_set_op_res_gpointer (operation_result,
-                                                           g_object_ref (client->priv->chooser),
-                                                           (GDestroyNotify)
-                                                           g_object_unref);
-                g_simple_async_result_complete_in_idle (operation_result);
-                g_object_unref (operation_result);
+                g_task_return_pointer (task,
+                                       g_object_ref (client->priv->chooser),
+                                       (GDestroyNotify) g_object_unref);
+                g_object_unref (task);
                 return;
         }
 
@@ -1519,7 +1461,7 @@ gdm_client_get_chooser (GdmClient           *client,
                                     cancellable,
                                     (GAsyncReadyCallback)
                                     on_connection_opened_for_chooser,
-                                    operation_result);
+                                    task);
 }
 
 /**
@@ -1542,14 +1484,12 @@ gdm_client_get_chooser_finish (GdmClient       *client,
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->chooser != NULL) {
+        if (client->priv->chooser != NULL)
                 return g_object_ref (client->priv->chooser);
-        } else if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                                          error)) {
-                return NULL;
-        }
 
-        chooser = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+        chooser = g_task_propagate_pointer (G_TASK (result), error);
+        if (chooser == NULL)
+                return NULL;
 
         client->priv->chooser = chooser;
 
@@ -1567,7 +1507,7 @@ gdm_client_get_chooser_finish (GdmClient       *client,
                            g_clear_object,
                            &client->priv->manager);
 
-        return g_object_ref (chooser);
+        return chooser;
 }
 
 /**
@@ -1711,5 +1651,4 @@ gdm_client_set_enabled_extensions (GdmClient          *client,
                                    const char * const *extensions)
 {
         client->priv->enabled_extensions = g_strdupv ((char **) extensions);
-
 }
-- 
2.32.0


From 1e36e8d766210c4e0e050d29c70c91430d5c49de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 26 Feb 2018 19:52:50 +0100
Subject: [PATCH 03/19] libgdm: "Fix" a memory leak

The gdm_available_sessions_map hash table is set up with a value-free
function that frees the struct itself, but not its contents.

Of course elements are never removed from the map, so this fix doesn't
matter in practice.

https://bugzilla.gnome.org/show_bug.cgi?id=793855
---
 libgdm/gdm-sessions.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c
index ee981350..8bf7bd75 100644
--- a/libgdm/gdm-sessions.c
+++ b/libgdm/gdm-sessions.c
@@ -48,6 +48,16 @@ static GHashTable *gdm_available_sessions_map;
 
 static gboolean gdm_sessions_map_is_initialized = FALSE;
 
+static void
+gdm_session_file_free (GdmSessionFile *session)
+{
+  g_free (session->id);
+  g_free (session->path);
+  g_free (session->translated_name);
+  g_free (session->translated_comment);
+  g_free (session);
+}
+
 /* adapted from gnome-menus desktop-entries.c */
 static gboolean
 key_file_is_relevant (GKeyFile     *key_file)
@@ -223,7 +233,7 @@ collect_sessions (void)
 
         if (gdm_available_sessions_map == NULL) {
                 gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                                    g_free, g_free);
+                                                                    g_free, (GDestroyNotify)gdm_session_file_free);
         }
 
         for (i = 0; xorg_search_dirs [i] != NULL; i++) {
-- 
2.32.0


From 4654042d22c71da599d60a7e2f0570acf3d4a166 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 9 May 2018 15:43:27 +0100
Subject: [PATCH 04/19] libgdm: Don't unref a connection that's in use

If an async task tries to reuse an open connection,
it erroneously explicitly unrefs it. That is incorrect,
because there are weak references in use to handle
disposing the connection when its no longer in use.

This commit makes sure the local connection object
in open_connection is nullified so the connection
doesn't get autofree'd.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index bcae8ba2..c017bf86 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -583,6 +583,8 @@ gdm_client_open_connection_finish (GdmClient      *client,
 
         if (client->priv->connection == NULL) {
                 client->priv->connection = g_steal_pointer (&connection);
+        } else if (client->priv->connection == connection) {
+                connection = NULL;
         }
 
         finish_pending_opens (client, NULL);
-- 
2.32.0


From ccba35d58ae27b02979310d5914a96186afa31de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 9 May 2018 15:43:27 +0100
Subject: [PATCH 05/19] libgdm: add weak pointer for connection object

At the moment we fail to nullify GdmClient's
connection to GDM when the connection is disposed.

This commit adds a weak pointer to correct that mistake.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index c017bf86..b5f35306 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -460,6 +460,10 @@ gdm_client_open_connection_sync (GdmClient      *client,
                         g_clear_pointer (&client->priv->address, g_free);
                         goto out;
                 }
+
+                g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
+                                           (gpointer *)
+                                           &client->priv->connection);
         } else {
                 client->priv->connection = g_object_ref (client->priv->connection);
         }
@@ -583,6 +587,8 @@ gdm_client_open_connection_finish (GdmClient      *client,
 
         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;
         }
@@ -1616,6 +1622,12 @@ gdm_client_finalize (GObject *object)
                                               &client->priv->chooser);
         }
 
+        if (client->priv->connection != NULL) {
+                g_object_remove_weak_pointer (G_OBJECT (client->priv->connection),
+                                              (gpointer *)
+                                              &client->priv->connection);
+        }
+
         g_clear_object (&client->priv->manager);
         g_clear_object (&client->priv->connection);
 
-- 
2.32.0


From 6f8498ca6ccf09877d262077becd71f26c941174 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 May 2018 14:48:31 -0400
Subject: [PATCH 06/19] 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 b5f35306..61bcbd37 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -51,7 +51,6 @@ struct GdmClientPrivate
         GDBusConnection    *connection;
         char               *address;
 
-        GList              *pending_opens;
         char              **enabled_extensions;
 };
 
@@ -421,53 +420,50 @@ gdm_client_open_connection_sync (GdmClient      *client,
 
         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;
+        }
 
-                g_debug ("GdmClient: connecting to address: %s", client->priv->address);
+        ret = gdm_manager_call_open_session_sync (client->priv->manager,
+                                                  &client->priv->address,
+                                                  cancellable,
+                                                  error);
 
-                client->priv->connection = g_dbus_connection_new_for_address_sync (client->priv->address,
-                                                                                   G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
-                                                                                   NULL,
-                                                                                   cancellable,
-                                                                                   error);
+        if (!ret) {
+                g_clear_object (&client->priv->manager);
+                goto out;
+        }
 
-                if (client->priv->connection == NULL) {
-                        g_clear_object (&client->priv->manager);
-                        g_clear_pointer (&client->priv->address, g_free);
-                        goto out;
-                }
+        g_debug ("GdmClient: connecting to address: %s", client->priv->address);
 
-                g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
-                                           (gpointer *)
-                                           &client->priv->connection);
-        } else {
-                client->priv->connection = g_object_ref (client->priv->connection);
+        client->priv->connection = g_dbus_connection_new_for_address_sync (client->priv->address,
+                                                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+                                                                           NULL,
+                                                                           cancellable,
+                                                                           error);
+
+        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;
 }
@@ -551,25 +547,6 @@ on_got_manager_for_opening_connection (GdmClient           *client,
                                        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,
@@ -581,7 +558,6 @@ gdm_client_open_connection_finish (GdmClient      *client,
 
         connection = g_task_propagate_pointer (G_TASK (result), error);
         if (connection == NULL) {
-                finish_pending_opens (client, *error);
                 return FALSE;
         }
 
@@ -593,7 +569,6 @@ gdm_client_open_connection_finish (GdmClient      *client,
                 connection = NULL;
         }
 
-        finish_pending_opens (client, NULL);
         return TRUE;
 }
 
@@ -620,17 +595,11 @@ gdm_client_open_connection (GdmClient           *client,
             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);
 }
 
 /**
-- 
2.32.0


From f57e11bf9a68564eedba4f0d75c122862a1ea771 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 May 2018 15:49:50 -0400
Subject: [PATCH 07/19] libgdm: fix pointer/boolean task confusion

The manager fetching code in GdmClient treats its task
return value as boolean, but it's actually a pointer (the manager)

This commit corrects the confusion.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 61bcbd37..a4a0e283 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -390,11 +390,13 @@ on_got_manager_for_reauthentication (GdmClient           *client,
                                      GTask               *task)
 {
         GCancellable *cancellable;
+        GdmManager   *manager;
         char         *username;
         GError       *error;
 
         error = NULL;
-        if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+        manager = g_task_propagate_pointer (G_TASK (result), &error);
+        if (manager == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
@@ -530,10 +532,12 @@ on_got_manager_for_opening_connection (GdmClient           *client,
                                        GTask               *task)
 {
         GCancellable *cancellable;
+        GdmManager   *manager;
         GError       *error;
 
         error = NULL;
-        if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+        manager = g_task_propagate_pointer (G_TASK (result), &error);
+        if (manager == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
-- 
2.32.0


From 431739427e9dbdafc0ed011760f35fd6ee1af95b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 May 2018 15:57:14 -0400
Subject: [PATCH 08/19] libgdm: don't keep manager proxy around longer than we
 need it
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Right now we keep the manager proxy alive long after we need it.
It doesn't get cleared until one of the other proxies go away.

That is not only unnecessary but illogical and confusing.

This commit changes the manager proxy to be transient—only alive
long enough to get what we need from it.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index a4a0e283..c34121e6 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -40,8 +40,6 @@
 
 struct GdmClientPrivate
 {
-        GdmManager         *manager;
-
         GdmUserVerifier    *user_verifier;
         GHashTable         *user_verifier_extensions;
 
@@ -74,34 +72,24 @@ gdm_client_error_quark (void)
 }
 
 static void
-on_got_manager (GdmManager          *manager,
+on_got_manager (GObject             *object,
                 GAsyncResult        *result,
                 GTask               *task)
 {
         GdmClient *client;
-        GdmManager       *new_manager;
-        GError           *error;
+        GError    *error;
+        g_autoptr(GdmManager) manager = NULL;
 
         client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
 
         error = NULL;
-        new_manager = gdm_manager_proxy_new_finish (result, &error);
-
-        if (client->priv->manager == NULL) {
-                client->priv->manager = new_manager;
-
-        } else {
-                g_object_ref (client->priv->manager);
-                g_object_unref (new_manager);
-
-                g_clear_error (&error);
-        }
+        manager = gdm_manager_proxy_new_finish (result, &error);
 
         if (error != NULL) {
                 g_task_return_error (task, error);
         } else {
                 g_task_return_pointer (task,
-                                       g_object_ref (client->priv->manager),
+                                       g_object_ref (manager),
                                        (GDestroyNotify) g_object_unref);
         }
 
@@ -122,14 +110,6 @@ get_manager (GdmClient           *client,
                            callback,
                            user_data);
 
-        if (client->priv->manager != NULL) {
-                g_task_return_pointer (task,
-                                       g_object_ref (client->priv->manager),
-                                       (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
-                return;
-        }
-
         gdm_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
                                        G_DBUS_PROXY_FLAGS_NONE,
                                        "org.gnome.DisplayManager",
@@ -404,7 +384,7 @@ on_got_manager_for_reauthentication (GdmClient           *client,
 
         cancellable = g_task_get_cancellable (task);
         username = g_object_get_data (G_OBJECT (task), "username");
-        gdm_manager_call_open_reauthentication_channel (client->priv->manager,
+        gdm_manager_call_open_reauthentication_channel (manager,
                                                         username,
                                                         cancellable,
                                                         (GAsyncReadyCallback)
@@ -418,6 +398,7 @@ gdm_client_open_connection_sync (GdmClient      *client,
                                  GCancellable   *cancellable,
                                  GError        **error)
 {
+        g_autoptr(GdmManager) manager = NULL;
         gboolean ret;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
@@ -427,24 +408,23 @@ gdm_client_open_connection_sync (GdmClient      *client,
                 return TRUE;
         }
 
-        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);
+        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) {
+        if (manager == NULL) {
                 goto out;
         }
 
-        ret = gdm_manager_call_open_session_sync (client->priv->manager,
+        ret = gdm_manager_call_open_session_sync (manager,
                                                   &client->priv->address,
                                                   cancellable,
                                                   error);
 
         if (!ret) {
-                g_clear_object (&client->priv->manager);
                 goto out;
         }
 
@@ -457,7 +437,6 @@ gdm_client_open_connection_sync (GdmClient      *client,
                                                                            error);
 
         if (client->priv->connection == NULL) {
-                g_clear_object (&client->priv->manager);
                 g_clear_pointer (&client->priv->address, g_free);
                 goto out;
         }
@@ -544,7 +523,7 @@ on_got_manager_for_opening_connection (GdmClient           *client,
         }
 
         cancellable = g_task_get_cancellable (task);
-        gdm_manager_call_open_session (client->priv->manager,
+        gdm_manager_call_open_session (manager,
                                        cancellable,
                                        (GAsyncReadyCallback)
                                        on_session_opened,
@@ -627,28 +606,25 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                GError       **error)
 {
         GDBusConnection *connection;
+        g_autoptr(GdmManager) manager = NULL;
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
         char            *address;
 
         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);
+        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 (manager == NULL) {
+                goto out;
         }
 
-        ret = gdm_manager_call_open_reauthentication_channel_sync (client->priv->manager,
+        ret = gdm_manager_call_open_reauthentication_channel_sync (manager,
                                                                    username,
                                                                    &address,
                                                                    cancellable,
@@ -684,11 +660,6 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                    (GWeakNotify)
                                    g_object_unref,
                                    connection);
-
-                g_object_weak_ref (G_OBJECT (user_verifier),
-                                   (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->manager);
         }
 
  out:
@@ -791,10 +762,6 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->user_verifier),
                                            (gpointer *)
                                            &client->priv->user_verifier);
-                g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
-                                   (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->manager);
                 g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
                                    (GWeakNotify)
                                    g_clear_object,
@@ -941,11 +908,6 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
                            g_object_unref,
                            client->priv->connection);
 
-        g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
-                           (GWeakNotify)
-                           g_clear_object,
-                           &client->priv->manager);
-
         return user_verifier;
 }
 
@@ -1115,12 +1077,6 @@ gdm_client_get_greeter_finish (GdmClient       *client,
                            (GWeakNotify)
                            g_object_unref,
                            client->priv->connection);
-
-        g_object_weak_ref (G_OBJECT (client->priv->greeter),
-                           (GWeakNotify)
-                           g_clear_object,
-                           &client->priv->manager);
-
         return greeter;
 }
 
@@ -1161,10 +1117,6 @@ gdm_client_get_greeter_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->greeter),
                                            (gpointer *)
                                            &client->priv->greeter);
-                g_object_weak_ref (G_OBJECT (client->priv->greeter),
-                                   (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->manager);
                 g_object_weak_ref (G_OBJECT (client->priv->greeter),
                                    (GWeakNotify)
                                    g_clear_object,
@@ -1301,11 +1253,6 @@ gdm_client_get_remote_greeter_finish (GdmClient     *client,
                            g_object_unref,
                            client->priv->connection);
 
-        g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
-                           (GWeakNotify)
-                           g_clear_object,
-                           &client->priv->manager);
-
         return remote_greeter;
 }
 
@@ -1345,10 +1292,6 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->remote_greeter),
                                            (gpointer *)
                                            &client->priv->remote_greeter);
-                g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
-                                   (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->manager);
                 g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
                                    (GWeakNotify)
                                    g_clear_object,
@@ -1483,11 +1426,6 @@ gdm_client_get_chooser_finish (GdmClient       *client,
                            g_object_unref,
                            client->priv->connection);
 
-        g_object_weak_ref (G_OBJECT (client->priv->chooser),
-                           (GWeakNotify)
-                           g_clear_object,
-                           &client->priv->manager);
-
         return chooser;
 }
 
@@ -1528,10 +1466,6 @@ gdm_client_get_chooser_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->chooser),
                                            (gpointer *)
                                            &client->priv->chooser);
-                g_object_weak_ref (G_OBJECT (client->priv->chooser),
-                                   (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->manager);
                 g_object_weak_ref (G_OBJECT (client->priv->chooser),
                                    (GWeakNotify)
                                    g_clear_object,
@@ -1601,7 +1535,6 @@ gdm_client_finalize (GObject *object)
                                               &client->priv->connection);
         }
 
-        g_clear_object (&client->priv->manager);
         g_clear_object (&client->priv->connection);
 
         g_strfreev (client->priv->enabled_extensions);
-- 
2.32.0


From 85232f330401e574a74c62ab829b740ead59885d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 May 2018 17:02:36 -0400
Subject: [PATCH 09/19] libgdm: use g_object_unref instead of g_clear_object
 for weakrefs

At the moment we add a weakref on each proxy to the connection
object.  For the _sync variant functions, When the weakref fires,
they call g_clear_object, clearing the connection, even if other
proxies still have a reference.

This commit changes that weak ref code to use g_object_unref instead.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index c34121e6..e02e3ea5 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -764,8 +764,8 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                                            &client->priv->user_verifier);
                 g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
                                    (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->connection);
+                                   g_object_unref,
+                                   client->priv->connection);
 
                 if (client->priv->enabled_extensions != NULL) {
                         gboolean res;
@@ -1119,8 +1119,8 @@ gdm_client_get_greeter_sync (GdmClient     *client,
                                            &client->priv->greeter);
                 g_object_weak_ref (G_OBJECT (client->priv->greeter),
                                    (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->connection);
+                                   g_object_unref,
+                                   client->priv->connection);
 
                 query_for_timed_login_requested_signal (client->priv->greeter);
         }
@@ -1294,8 +1294,8 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
                                            &client->priv->remote_greeter);
                 g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
                                    (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->connection);
+                                   g_object_unref,
+                                   client->priv->connection);
         }
 
         return client->priv->remote_greeter;
@@ -1468,8 +1468,8 @@ gdm_client_get_chooser_sync (GdmClient     *client,
                                            &client->priv->chooser);
                 g_object_weak_ref (G_OBJECT (client->priv->chooser),
                                    (GWeakNotify)
-                                   g_clear_object,
-                                   &client->priv->connection);
+                                   g_object_unref,
+                                   client->priv->connection);
         }
 
         return client->priv->chooser;
-- 
2.32.0


From dc66c87bd69d4fc91d3e5e94734a51ee3e85a19a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 14 May 2018 16:32:25 -0400
Subject: [PATCH 10/19] libgdm: get connection explicitly

At the moment we call gdm_client_open_connection and when it finishes,
assume client->priv->connection is implicitly initialized.

This commit makes the operation more explicit by changing
gdm_client_open_connection to gdm_client_get_connection and returning
the GDBusConnection object directly, instead of returning a boolean.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index e02e3ea5..e7b93e38 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -393,10 +393,10 @@ on_got_manager_for_reauthentication (GdmClient           *client,
 
 }
 
-static gboolean
-gdm_client_open_connection_sync (GdmClient      *client,
-                                 GCancellable   *cancellable,
-                                 GError        **error)
+static GDBusConnection *
+gdm_client_get_connection_sync (GdmClient      *client,
+                                GCancellable   *cancellable,
+                                GError        **error)
 {
         g_autoptr(GdmManager) manager = NULL;
         gboolean ret;
@@ -404,8 +404,7 @@ gdm_client_open_connection_sync (GdmClient      *client,
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
         if (client->priv->connection != NULL) {
-                g_object_ref (client->priv->connection);
-                return TRUE;
+                return g_object_ref (client->priv->connection);
         }
 
         manager = gdm_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
@@ -446,7 +445,7 @@ gdm_client_open_connection_sync (GdmClient      *client,
                                    &client->priv->connection);
 
  out:
-        return client->priv->connection != NULL;
+        return client->priv->connection;
 }
 
 static void
@@ -530,33 +529,31 @@ on_got_manager_for_opening_connection (GdmClient           *client,
                                        task);
 }
 
-static gboolean
-gdm_client_open_connection_finish (GdmClient      *client,
-                                   GAsyncResult   *result,
-                                   GError        **error)
+static GDBusConnection *
+gdm_client_get_connection_finish (GdmClient      *client,
+                                  GAsyncResult   *result,
+                                  GError        **error)
 {
-        g_autoptr(GDBusConnection) connection = NULL;
+        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) {
-                return FALSE;
+                return NULL;
         }
 
         if (client->priv->connection == NULL) {
-                client->priv->connection = g_steal_pointer (&connection);
+                client->priv->connection = connection;
                 g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
                                            (gpointer *) &client->priv->connection);
-        } else if (client->priv->connection == connection) {
-                connection = NULL;
         }
 
-        return TRUE;
+        return g_object_ref (connection);
 }
 
 static void
-gdm_client_open_connection (GdmClient           *client,
+gdm_client_get_connection (GdmClient           *client,
                             GCancellable        *cancellable,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
@@ -743,15 +740,19 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                                    GCancellable  *cancellable,
                                    GError       **error)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
+
         if (client->priv->user_verifier != NULL) {
                 return g_object_ref (client->priv->user_verifier);
         }
 
-        if (!gdm_client_open_connection_sync (client, cancellable, error)) {
+        connection = gdm_client_get_connection_sync (client, cancellable, error);
+
+        if (connection == NULL) {
                 return NULL;
         }
 
-        client->priv->user_verifier = gdm_user_verifier_proxy_new_sync (client->priv->connection,
+        client->priv->user_verifier = gdm_user_verifier_proxy_new_sync (connection,
                                                                         G_DBUS_PROXY_FLAGS_NONE,
                                                                         NULL,
                                                                         SESSION_DBUS_PATH,
@@ -762,6 +763,7 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->user_verifier),
                                            (gpointer *)
                                            &client->priv->user_verifier);
+                g_object_ref (connection);
                 g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
                                    (GWeakNotify)
                                    g_object_unref,
@@ -805,22 +807,25 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
 }
 
 static void
-on_connection_opened_for_user_verifier (GdmClient          *client,
-                                        GAsyncResult       *result,
-                                        GTask              *task)
+on_connection_for_user_verifier (GdmClient          *client,
+                                 GAsyncResult       *result,
+                                 GTask              *task)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
-        if (!gdm_client_open_connection_finish (client, result, &error)) {
+        connection = gdm_client_get_connection_finish (client, result, &error);
+
+        if (connection == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
-        gdm_user_verifier_proxy_new (client->priv->connection,
+        gdm_user_verifier_proxy_new (connection,
                                      G_DBUS_PROXY_FLAGS_NONE,
                                      NULL,
                                      SESSION_DBUS_PATH,
@@ -863,10 +868,10 @@ gdm_client_get_user_verifier (GdmClient           *client,
                 return;
         }
 
-        gdm_client_open_connection (client,
+        gdm_client_get_connection (client,
                                     cancellable,
                                     (GAsyncReadyCallback)
-                                    on_connection_opened_for_user_verifier,
+                                    on_connection_for_user_verifier,
                                     task);
 }
 
@@ -975,22 +980,25 @@ on_greeter_proxy_created (GObject            *source,
 }
 
 static void
-on_connection_opened_for_greeter (GdmClient          *client,
-                                  GAsyncResult       *result,
-                                  GTask              *task)
+on_connection_for_greeter (GdmClient          *client,
+                           GAsyncResult       *result,
+                           GTask              *task)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
-        if (!gdm_client_open_connection_finish (client, result, &error)) {
+        connection = gdm_client_get_connection_finish (client, result, &error);
+
+        if (connection == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
-        gdm_greeter_proxy_new (client->priv->connection,
+        gdm_greeter_proxy_new (connection,
                                G_DBUS_PROXY_FLAGS_NONE,
                                NULL,
                                SESSION_DBUS_PATH,
@@ -1033,10 +1041,10 @@ gdm_client_get_greeter (GdmClient           *client,
                 return;
         }
 
-        gdm_client_open_connection (client,
+        gdm_client_get_connection (client,
                                     cancellable,
                                     (GAsyncReadyCallback)
-                                    on_connection_opened_for_greeter,
+                                    on_connection_for_greeter,
                                     task);
 }
 
@@ -1098,15 +1106,19 @@ gdm_client_get_greeter_sync (GdmClient     *client,
                              GCancellable  *cancellable,
                              GError       **error)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
+
         if (client->priv->greeter != NULL) {
                 return g_object_ref (client->priv->greeter);
         }
 
-        if (!gdm_client_open_connection_sync (client, cancellable, error)) {
+        connection = gdm_client_get_connection_sync (client, cancellable, error);
+
+        if (connection == NULL) {
                 return NULL;
         }
 
-        client->priv->greeter = gdm_greeter_proxy_new_sync (client->priv->connection,
+        client->priv->greeter = gdm_greeter_proxy_new_sync (connection,
                                                             G_DBUS_PROXY_FLAGS_NONE,
                                                             NULL,
                                                             SESSION_DBUS_PATH,
@@ -1150,22 +1162,25 @@ on_remote_greeter_proxy_created (GObject            *object,
 }
 
 static void
-on_connection_opened_for_remote_greeter (GdmClient          *client,
-                                         GAsyncResult       *result,
-                                         GTask              *task)
+on_connection_for_remote_greeter (GdmClient          *client,
+                                  GAsyncResult       *result,
+                                  GTask              *task)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
-        if (!gdm_client_open_connection_finish (client, result, &error)) {
+        connection = gdm_client_get_connection_finish (client, result, &error);
+
+        if (connection == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
-        gdm_remote_greeter_proxy_new (client->priv->connection,
+        gdm_remote_greeter_proxy_new (connection,
                                       G_DBUS_PROXY_FLAGS_NONE,
                                       NULL,
                                       SESSION_DBUS_PATH,
@@ -1208,10 +1223,10 @@ gdm_client_get_remote_greeter (GdmClient           *client,
                 return;
         }
 
-        gdm_client_open_connection (client,
+        gdm_client_get_connection (client,
                                     cancellable,
                                     (GAsyncReadyCallback)
-                                    on_connection_opened_for_remote_greeter,
+                                    on_connection_for_remote_greeter,
                                     task);
 }
 
@@ -1273,15 +1288,19 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
                                     GCancellable  *cancellable,
                                     GError       **error)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
+
         if (client->priv->remote_greeter != NULL) {
                 return g_object_ref (client->priv->remote_greeter);
         }
 
-        if (!gdm_client_open_connection_sync (client, cancellable, error)) {
+        connection = gdm_client_get_connection_sync (client, cancellable, error);
+
+        if (connection == NULL) {
                 return NULL;
         }
 
-        client->priv->remote_greeter = gdm_remote_greeter_proxy_new_sync (client->priv->connection,
+        client->priv->remote_greeter = gdm_remote_greeter_proxy_new_sync (connection,
                                                                           G_DBUS_PROXY_FLAGS_NONE,
                                                                           NULL,
                                                                           SESSION_DBUS_PATH,
@@ -1292,6 +1311,7 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->remote_greeter),
                                            (gpointer *)
                                            &client->priv->remote_greeter);
+                g_object_ref (connection);
                 g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
                                    (GWeakNotify)
                                    g_object_unref,
@@ -1323,22 +1343,25 @@ on_chooser_proxy_created (GObject            *source,
 }
 
 static void
-on_connection_opened_for_chooser (GdmClient          *client,
-                                  GAsyncResult       *result,
-                                  GTask              *task)
+on_connection_for_chooser (GdmClient          *client,
+                           GAsyncResult       *result,
+                           GTask              *task)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
         GError       *error;
 
         error = NULL;
-        if (!gdm_client_open_connection_finish (client, result, &error)) {
+        connection = gdm_client_get_connection_finish (client, result, &error);
+
+        if (connection == NULL) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
                 return;
         }
 
         cancellable = g_task_get_cancellable (task);
-        gdm_chooser_proxy_new (client->priv->connection,
+        gdm_chooser_proxy_new (connection,
                                G_DBUS_PROXY_FLAGS_NONE,
                                NULL,
                                SESSION_DBUS_PATH,
@@ -1381,10 +1404,10 @@ gdm_client_get_chooser (GdmClient           *client,
                 return;
         }
 
-        gdm_client_open_connection (client,
+        gdm_client_get_connection (client,
                                     cancellable,
                                     (GAsyncReadyCallback)
-                                    on_connection_opened_for_chooser,
+                                    on_connection_for_chooser,
                                     task);
 }
 
@@ -1421,6 +1444,7 @@ gdm_client_get_chooser_finish (GdmClient       *client,
                                    (gpointer *)
                                    &client->priv->chooser);
 
+        g_object_ref (connection);
         g_object_weak_ref (G_OBJECT (client->priv->chooser),
                            (GWeakNotify)
                            g_object_unref,
@@ -1446,16 +1470,19 @@ gdm_client_get_chooser_sync (GdmClient     *client,
                              GCancellable  *cancellable,
                              GError       **error)
 {
+        g_autoptr(GDBusConnection) connection = NULL;
 
         if (client->priv->chooser != NULL) {
                 return g_object_ref (client->priv->chooser);
         }
 
-        if (!gdm_client_open_connection_sync (client, cancellable, error)) {
+        connection = gdm_client_get_connection_sync (client, cancellable, error);
+
+        if (connection == NULL) {
                 return NULL;
         }
 
-        client->priv->chooser = gdm_chooser_proxy_new_sync (client->priv->connection,
+        client->priv->chooser = gdm_chooser_proxy_new_sync (connection,
                                                             G_DBUS_PROXY_FLAGS_NONE,
                                                             NULL,
                                                             SESSION_DBUS_PATH,
@@ -1466,6 +1493,7 @@ gdm_client_get_chooser_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->chooser),
                                            (gpointer *)
                                            &client->priv->chooser);
+                g_object_ref (connection);
                 g_object_weak_ref (G_OBJECT (client->priv->chooser),
                                    (GWeakNotify)
                                    g_object_unref,
-- 
2.32.0


From a1b491676c2849f4c366fb29a8bc8754056f7f4b Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
Date: Mon, 14 May 2018 16:32:25 -0400
Subject: [PATCH 11/19] libgdm: Drop weak refs on the GDBusConnection

The GDBusProxies hold a strong reference to the connection themselves,
so maintaining separate weak references is unnecessary.

This commit drops those extraneous weak references.

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

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index e7b93e38..f327344e 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -652,13 +652,6 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                           cancellable,
                                                           error);
 
-        if (user_verifier != NULL) {
-                g_object_weak_ref (G_OBJECT (user_verifier),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   connection);
-        }
-
  out:
         return user_verifier;
 }
@@ -763,12 +756,6 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->user_verifier),
                                            (gpointer *)
                                            &client->priv->user_verifier);
-                g_object_ref (connection);
-                g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   client->priv->connection);
-
                 if (client->priv->enabled_extensions != NULL) {
                         gboolean res;
 
@@ -908,11 +895,6 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
                                    (gpointer *)
                                    &client->priv->user_verifier);
 
-        g_object_weak_ref (G_OBJECT (client->priv->user_verifier),
-                           (GWeakNotify)
-                           g_object_unref,
-                           client->priv->connection);
-
         return user_verifier;
 }
 
@@ -1081,10 +1063,6 @@ gdm_client_get_greeter_finish (GdmClient       *client,
                                    (gpointer *)
                                    &client->priv->greeter);
 
-        g_object_weak_ref (G_OBJECT (client->priv->greeter),
-                           (GWeakNotify)
-                           g_object_unref,
-                           client->priv->connection);
         return greeter;
 }
 
@@ -1129,10 +1107,6 @@ gdm_client_get_greeter_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->greeter),
                                            (gpointer *)
                                            &client->priv->greeter);
-                g_object_weak_ref (G_OBJECT (client->priv->greeter),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   client->priv->connection);
 
                 query_for_timed_login_requested_signal (client->priv->greeter);
         }
@@ -1263,11 +1237,6 @@ gdm_client_get_remote_greeter_finish (GdmClient     *client,
                                    (gpointer *)
                                    &client->priv->remote_greeter);
 
-        g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
-                           (GWeakNotify)
-                           g_object_unref,
-                           client->priv->connection);
-
         return remote_greeter;
 }
 
@@ -1311,11 +1280,6 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->remote_greeter),
                                            (gpointer *)
                                            &client->priv->remote_greeter);
-                g_object_ref (connection);
-                g_object_weak_ref (G_OBJECT (client->priv->remote_greeter),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   client->priv->connection);
         }
 
         return client->priv->remote_greeter;
@@ -1444,12 +1408,6 @@ gdm_client_get_chooser_finish (GdmClient       *client,
                                    (gpointer *)
                                    &client->priv->chooser);
 
-        g_object_ref (connection);
-        g_object_weak_ref (G_OBJECT (client->priv->chooser),
-                           (GWeakNotify)
-                           g_object_unref,
-                           client->priv->connection);
-
         return chooser;
 }
 
@@ -1493,11 +1451,6 @@ gdm_client_get_chooser_sync (GdmClient     *client,
                 g_object_add_weak_pointer (G_OBJECT (client->priv->chooser),
                                            (gpointer *)
                                            &client->priv->chooser);
-                g_object_ref (connection);
-                g_object_weak_ref (G_OBJECT (client->priv->chooser),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   client->priv->connection);
         }
 
         return client->priv->chooser;
-- 
2.32.0


From 4d2da18f7d3fa79aeededcd1760d3a1ab75adfeb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 1 Jun 2018 17:07:41 +0200
Subject: [PATCH 12/19] libgdm: Unref the manager propagated from task

This instance has already been reffed when passed to the task, and since
we're stealing it with `g_task_propagate_pointer` it won't be unreffed.

We could also do this in the `on_reauthentication_channel_opened` callback
but since the new task will ref it anyway, we can just be clean and do it
here.
---
 libgdm/gdm-client.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index f327344e..fa4ba842 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -390,7 +390,7 @@ on_got_manager_for_reauthentication (GdmClient           *client,
                                                         (GAsyncReadyCallback)
                                                         on_reauthentication_channel_opened,
                                                         task);
-
+        g_object_unref (manager);
 }
 
 static GDBusConnection *
@@ -527,6 +527,8 @@ on_got_manager_for_opening_connection (GdmClient           *client,
                                        (GAsyncReadyCallback)
                                        on_session_opened,
                                        task);
+
+        g_object_unref (manager);
 }
 
 static GDBusConnection *
-- 
2.32.0


From d3b1cc17bb93de7025b2204c09545363f6f15264 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 1 Jun 2018 17:16:35 +0200
Subject: [PATCH 13/19] libgdm: Don't double-ref the connection got from task

Both if we re-use the shared connection in `gdm_client_get_connection` and if
we create a new one in `on_connected`, we steal the pointer here by using
`g_task_propagate_pointer` and thus we don't have to add an additional
reference to this connection when returning, or it won't ever be consumed by
function customers.
---
 libgdm/gdm-client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index fa4ba842..36292148 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -536,7 +536,7 @@ gdm_client_get_connection_finish (GdmClient      *client,
                                   GAsyncResult   *result,
                                   GError        **error)
 {
-        GDBusConnection *connection = NULL;
+        GDBusConnection *connection;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
@@ -551,7 +551,7 @@ gdm_client_get_connection_finish (GdmClient      *client,
                                            (gpointer *) &client->priv->connection);
         }
 
-        return g_object_ref (connection);
+        return connection;
 }
 
 static void
-- 
2.32.0


From 1f5678c65c96d2534a687a2344fdc0655a832c47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 1 Jun 2018 17:20:17 +0200
Subject: [PATCH 14/19] libgdm: Don't leak connection on sync re-authentication

---
 libgdm/gdm-client.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 36292148..335a040a 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -604,7 +604,7 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                GCancellable  *cancellable,
                                                GError       **error)
 {
-        GDBusConnection *connection;
+        g_autoptr(GDBusConnection) connection = NULL;
         g_autoptr(GdmManager) manager = NULL;
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
-- 
2.32.0


From d92f4d93ce2d5d25db5777459fcd51e2d80645a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 1 Jun 2018 17:22:20 +0200
Subject: [PATCH 15/19] libgdm: Use auto-pointers and cleanup code

---
 libgdm/gdm-client.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 335a040a..7b42b6c9 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -606,9 +606,9 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
 {
         g_autoptr(GDBusConnection) connection = NULL;
         g_autoptr(GdmManager) manager = NULL;
+        g_autofree char *address = NULL;
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
-        char            *address;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
@@ -620,7 +620,7 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                       error);
 
         if (manager == NULL) {
-                goto out;
+                return NULL;
         }
 
         ret = gdm_manager_call_open_reauthentication_channel_sync (manager,
@@ -630,10 +630,10 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                                    error);
 
         if (!ret) {
-                goto out;
+                return NULL;
         }
 
-        g_debug ("GdmClient: connecting to address: %s", client->priv->address);
+        g_debug ("GdmClient: connecting to address: %s", address);
 
         connection = g_dbus_connection_new_for_address_sync (address,
                                                              G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
@@ -642,10 +642,8 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                              error);
 
         if (connection == NULL) {
-                g_free (address);
-                goto out;
+                return NULL;
         }
-        g_free (address);
 
         user_verifier = gdm_user_verifier_proxy_new_sync (connection,
                                                           G_DBUS_PROXY_FLAGS_NONE,
@@ -654,7 +652,6 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                           cancellable,
                                                           error);
 
- out:
         return user_verifier;
 }
 
-- 
2.32.0


From 7782778781d0718882c005f94aed9f831e17aa48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Sat, 2 Jun 2018 19:34:08 +0200
Subject: [PATCH 16/19] libgdb: Try to reuse connections from the available
 proxies

Instead of using the hard-to-maintain shared pointer to the dbus connection
to the manager and reset it when the proxies that use it are deleted, just
look which proxy is currently available and try to reuse the connection
from it.

Fixes #386
---
 libgdm/gdm-client.c | 70 +++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 31 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 7b42b6c9..acf016a4 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -46,7 +46,6 @@ struct GdmClientPrivate
         GdmGreeter         *greeter;
         GdmRemoteGreeter   *remote_greeter;
         GdmChooser         *chooser;
-        GDBusConnection    *connection;
         char               *address;
 
         char              **enabled_extensions;
@@ -71,6 +70,28 @@ gdm_client_error_quark (void)
         return error_quark;
 }
 
+static GDBusConnection *
+gdm_client_get_open_connection (GdmClient *client)
+{
+        GDBusProxy *proxy = NULL;
+
+        if (client->priv->user_verifier != NULL) {
+                proxy = G_DBUS_PROXY (client->priv->user_verifier);
+        } else if (client->priv->greeter != NULL) {
+                proxy = G_DBUS_PROXY (client->priv->greeter);
+        } else if (client->priv->remote_greeter != NULL) {
+                proxy = G_DBUS_PROXY (client->priv->remote_greeter);
+        } else if (client->priv->chooser != NULL) {
+                proxy = G_DBUS_PROXY (client->priv->chooser);
+        }
+
+        if (proxy != NULL) {
+                return g_dbus_proxy_get_connection (proxy);
+        }
+
+        return NULL;
+}
+
 static void
 on_got_manager (GObject             *object,
                 GAsyncResult        *result,
@@ -399,12 +420,15 @@ gdm_client_get_connection_sync (GdmClient      *client,
                                 GError        **error)
 {
         g_autoptr(GdmManager) manager = NULL;
+        GDBusConnection *connection;
         gboolean ret;
 
         g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
 
-        if (client->priv->connection != NULL) {
-                return g_object_ref (client->priv->connection);
+        connection = gdm_client_get_open_connection (client);
+
+        if (connection != NULL) {
+                return g_object_ref (connection);
         }
 
         manager = gdm_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
@@ -429,23 +453,19 @@ gdm_client_get_connection_sync (GdmClient      *client,
 
         g_debug ("GdmClient: connecting to address: %s", client->priv->address);
 
-        client->priv->connection = g_dbus_connection_new_for_address_sync (client->priv->address,
-                                                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
-                                                                           NULL,
-                                                                           cancellable,
-                                                                           error);
+        connection = g_dbus_connection_new_for_address_sync (client->priv->address,
+                                                             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+                                                             NULL,
+                                                             cancellable,
+                                                             error);
 
-        if (client->priv->connection == NULL) {
+        if (connection == NULL) {
                 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;
+        return connection;
 }
 
 static void
@@ -545,12 +565,6 @@ gdm_client_get_connection_finish (GdmClient      *client,
                 return NULL;
         }
 
-        if (client->priv->connection == NULL) {
-                client->priv->connection = connection;
-                g_object_add_weak_pointer (G_OBJECT (client->priv->connection),
-                                           (gpointer *) &client->priv->connection);
-        }
-
         return connection;
 }
 
@@ -561,6 +575,7 @@ gdm_client_get_connection (GdmClient           *client,
                             gpointer             user_data)
 {
         GTask *task;
+        GDBusConnection *connection;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
@@ -569,9 +584,10 @@ gdm_client_get_connection (GdmClient           *client,
                            callback,
                            user_data);
 
-        if (client->priv->connection != NULL) {
+        connection = gdm_client_get_open_connection (client);
+        if (connection != NULL) {
             g_task_return_pointer (task,
-                                   g_object_ref (client->priv->connection),
+                                   g_object_ref (connection),
                                    (GDestroyNotify) g_object_unref);
             g_object_unref (task);
             return;
@@ -775,7 +791,7 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
                                             if (strcmp (client->priv->enabled_extensions[i],
                                                         gdm_user_verifier_choice_list_interface_info ()->name) == 0) {
                                                         GdmUserVerifierChoiceList *choice_list_interface;
-                                                        choice_list_interface = gdm_user_verifier_choice_list_proxy_new_sync (client->priv->connection,
+                                                        choice_list_interface = gdm_user_verifier_choice_list_proxy_new_sync (connection,
                                                                                                                               G_DBUS_PROXY_FLAGS_NONE,
                                                                                                                               NULL,
                                                                                                                               SESSION_DBUS_PATH,
@@ -1509,14 +1525,6 @@ gdm_client_finalize (GObject *object)
                                               &client->priv->chooser);
         }
 
-        if (client->priv->connection != NULL) {
-                g_object_remove_weak_pointer (G_OBJECT (client->priv->connection),
-                                              (gpointer *)
-                                              &client->priv->connection);
-        }
-
-        g_clear_object (&client->priv->connection);
-
         g_strfreev (client->priv->enabled_extensions);
         g_free (client->priv->address);
 
-- 
2.32.0


From a01fc3ca1a9c1321f8782547d9487838007091e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Sat, 2 Jun 2018 19:44:24 +0200
Subject: [PATCH 17/19] libgdm: Don't save manager address

There's no need to keep the manager connection address around, and
use autofree to clean it up
---
 libgdm/gdm-client.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index acf016a4..0e8bf439 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -46,7 +46,6 @@ struct GdmClientPrivate
         GdmGreeter         *greeter;
         GdmRemoteGreeter   *remote_greeter;
         GdmChooser         *chooser;
-        char               *address;
 
         char              **enabled_extensions;
 };
@@ -420,6 +419,7 @@ gdm_client_get_connection_sync (GdmClient      *client,
                                 GError        **error)
 {
         g_autoptr(GdmManager) manager = NULL;
+        g_autofree char *address = NULL;
         GDBusConnection *connection;
         gboolean ret;
 
@@ -439,32 +439,26 @@ gdm_client_get_connection_sync (GdmClient      *client,
                                                       error);
 
         if (manager == NULL) {
-                goto out;
+                return NULL;
         }
 
         ret = gdm_manager_call_open_session_sync (manager,
-                                                  &client->priv->address,
+                                                  &address,
                                                   cancellable,
                                                   error);
 
         if (!ret) {
-                goto out;
+                return NULL;
         }
 
-        g_debug ("GdmClient: connecting to address: %s", client->priv->address);
+        g_debug ("GdmClient: connecting to address: %s", address);
 
-        connection = g_dbus_connection_new_for_address_sync (client->priv->address,
+        connection = g_dbus_connection_new_for_address_sync (address,
                                                              G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                                              NULL,
                                                              cancellable,
                                                              error);
 
-        if (connection == NULL) {
-                g_clear_pointer (&client->priv->address, g_free);
-                goto out;
-        }
-
- out:
         return connection;
 }
 
@@ -497,6 +491,7 @@ on_session_opened (GdmManager         *manager,
                    GTask              *task)
 {
         GdmClient *client;
+        g_autofree char  *address = NULL;
         GCancellable     *cancellable;
         GError           *error;
 
@@ -504,7 +499,7 @@ on_session_opened (GdmManager         *manager,
 
         error = NULL;
         if (!gdm_manager_call_open_session_finish (manager,
-                                                   &client->priv->address,
+                                                   &address,
                                                    result,
                                                    &error)) {
                 g_task_return_error (task, error);
@@ -514,7 +509,7 @@ on_session_opened (GdmManager         *manager,
         }
 
         cancellable = g_task_get_cancellable (task);
-        g_dbus_connection_new_for_address (client->priv->address,
+        g_dbus_connection_new_for_address (address,
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL,
                                            cancellable,
@@ -1526,7 +1521,6 @@ gdm_client_finalize (GObject *object)
         }
 
         g_strfreev (client->priv->enabled_extensions);
-        g_free (client->priv->address);
 
         G_OBJECT_CLASS (gdm_client_parent_class)->finalize (object);
 }
-- 
2.32.0


From aca3d13d452ecf1a8e1e68ce955c8117bb99de7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 4 Jun 2018 19:13:04 +0200
Subject: [PATCH 18/19] libgdm: Return NULL on invalid client instances

---
 libgdm/gdm-client.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 0e8bf439..28cb7253 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -423,7 +423,7 @@ gdm_client_get_connection_sync (GdmClient      *client,
         GDBusConnection *connection;
         gboolean ret;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         connection = gdm_client_get_open_connection (client);
 
@@ -553,7 +553,7 @@ gdm_client_get_connection_finish (GdmClient      *client,
 {
         GDBusConnection *connection;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         connection = g_task_propagate_pointer (G_TASK (result), error);
         if (connection == NULL) {
@@ -621,7 +621,7 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         manager = gdm_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                       G_DBUS_PROXY_FLAGS_NONE,
@@ -722,7 +722,7 @@ gdm_client_open_reauthentication_channel_finish (GdmClient       *client,
                                                  GAsyncResult    *result,
                                                  GError         **error)
 {
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         return g_task_propagate_pointer (G_TASK (result), error);
 }
@@ -890,7 +890,7 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
 {
         GdmUserVerifier *user_verifier;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         if (client->priv->user_verifier != NULL)
                 return g_object_ref (client->priv->user_verifier);
@@ -1058,7 +1058,7 @@ gdm_client_get_greeter_finish (GdmClient       *client,
 {
         GdmGreeter *greeter;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         if (client->priv->greeter != NULL)
                 return g_object_ref (client->priv->greeter);
@@ -1232,7 +1232,7 @@ gdm_client_get_remote_greeter_finish (GdmClient     *client,
 {
         GdmRemoteGreeter *remote_greeter;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         if (client->priv->remote_greeter != NULL)
                 return g_object_ref (client->priv->remote_greeter);
@@ -1403,7 +1403,7 @@ gdm_client_get_chooser_finish (GdmClient       *client,
 {
         GdmChooser *chooser;
 
-        g_return_val_if_fail (GDM_IS_CLIENT (client), FALSE);
+        g_return_val_if_fail (GDM_IS_CLIENT (client), NULL);
 
         if (client->priv->chooser != NULL)
                 return g_object_ref (client->priv->chooser);
-- 
2.32.0


From 71c41056684763ca0fea3ec1db5b56c5ffe20f7d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 4 Jun 2018 19:11:25 +0200
Subject: [PATCH 19/19] libgdm: use g_autoptr to manage objects lifecycle

Using auto pointers allows to manage things in a cleaner way without having
to manually unref things before returning.
---
 libgdm/gdm-client.c | 264 +++++++++++++++++++-------------------------
 1 file changed, 111 insertions(+), 153 deletions(-)

diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 28cb7253..f9e3faee 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -94,27 +94,23 @@ gdm_client_get_open_connection (GdmClient *client)
 static void
 on_got_manager (GObject             *object,
                 GAsyncResult        *result,
-                GTask               *task)
+                gpointer             user_data)
 {
-        GdmClient *client;
-        GError    *error;
+        g_autoptr(GTask)      task = user_data;
+        g_autoptr(GdmClient)  client = NULL;
         g_autoptr(GdmManager) manager = NULL;
+        g_autoptr(GError)     error = NULL;
 
         client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
-
-        error = NULL;
         manager = gdm_manager_proxy_new_finish (result, &error);
 
         if (error != NULL) {
-                g_task_return_error (task, error);
+                g_task_return_error (task, g_steal_pointer (&error));
         } else {
                 g_task_return_pointer (task,
-                                       g_object_ref (manager),
+                                       g_steal_pointer (&manager),
                                        (GDestroyNotify) g_object_unref);
         }
-
-        g_object_unref (task);
-        g_object_unref (client);
 }
 
 static void
@@ -135,7 +131,6 @@ get_manager (GdmClient           *client,
                                        "org.gnome.DisplayManager",
                                        "/org/gnome/DisplayManager/Manager",
                                        cancellable,
-                                       (GAsyncReadyCallback)
                                        on_got_manager,
                                        task);
 }
@@ -200,7 +195,7 @@ on_user_verifier_choice_list_proxy_created (GObject            *source,
 {
         GdmClient                 *client;
         GdmUserVerifierChoiceList *choice_list;
-        GError                    *error = NULL;
+        g_autoptr(GError)          error = NULL;
 
         client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
 
@@ -208,7 +203,6 @@ on_user_verifier_choice_list_proxy_created (GObject            *source,
 
         if (choice_list == NULL) {
                 g_debug ("Couldn't create UserVerifier ChoiceList proxy: %s", error->message);
-                g_clear_error (&error);
                 g_hash_table_remove (client->priv->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name);
         } else {
                 g_hash_table_replace (client->priv->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name, choice_list);
@@ -225,7 +219,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
         GdmClient *client;
         GCancellable *cancellable;
         GDBusConnection *connection;
-        GError    *error = NULL;
+        g_autoptr(GError) error = NULL;
         size_t     i;
 
         client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
@@ -236,7 +230,6 @@ on_user_verifier_extensions_enabled (GdmUserVerifier    *user_verifier,
         if (error != NULL) {
                 g_debug ("Couldn't enable user verifier extensions: %s",
                          error->message);
-                g_clear_error (&error);
                 complete_user_verifier_proxy_operation (client, data);
                 return;
         }
@@ -284,17 +277,17 @@ free_interface_skeleton (GDBusInterfaceSkeleton *interface)
 static void
 on_user_verifier_proxy_created (GObject            *source,
                                 GAsyncResult       *result,
-                                GTask              *task)
+                                gpointer            user_data)
 {
         GdmClient       *self;
-        GdmUserVerifier *user_verifier;
         GCancellable    *cancellable = NULL;
-        GError          *error = NULL;
+        g_autoptr(GdmUserVerifier) user_verifier = NULL;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GError)          error = NULL;
 
         user_verifier = gdm_user_verifier_proxy_new_finish (result, &error);
         if (user_verifier == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -304,9 +297,8 @@ on_user_verifier_proxy_created (GObject            *source,
         if (self->priv->enabled_extensions == NULL) {
                 g_debug ("no enabled extensions");
                 g_task_return_pointer (task,
-                                       user_verifier,
+                                       g_steal_pointer (&user_verifier),
                                        (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
                 return;
         }
 
@@ -323,23 +315,21 @@ on_user_verifier_proxy_created (GObject            *source,
                                                   (GAsyncReadyCallback)
                                                   on_user_verifier_extensions_enabled,
                                                   user_verifier_data_new (task, user_verifier));
-        g_object_unref (user_verifier);
 }
 
 static void
 on_reauthentication_channel_connected (GObject            *source_object,
                                        GAsyncResult       *result,
-                                       GTask              *task)
+                                       gpointer            user_data)
 {
-        GDBusConnection *connection;
         GCancellable *cancellable;
-        GError       *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = g_dbus_connection_new_for_address_finish (result, &error);
         if (!connection) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -349,28 +339,25 @@ on_reauthentication_channel_connected (GObject            *source_object,
                                      NULL,
                                      SESSION_DBUS_PATH,
                                      cancellable,
-                                     (GAsyncReadyCallback)
                                      on_user_verifier_proxy_created,
-                                     task);
-        g_object_unref (connection);
+                                     g_steal_pointer (&task));
 }
 
 static void
 on_reauthentication_channel_opened (GdmManager         *manager,
                                     GAsyncResult       *result,
-                                    GTask              *task)
+                                    gpointer            user_data)
 {
         GCancellable *cancellable;
-        char         *address;
-        GError       *error;
+        g_autoptr(GTask)  task = user_data;
+        g_autoptr(GError) error = NULL;
+        g_autofree char  *address = NULL;
 
-        error = NULL;
         if (!gdm_manager_call_open_reauthentication_channel_finish (manager,
                                                                     &address,
                                                                     result,
                                                                     &error)) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -379,26 +366,24 @@ on_reauthentication_channel_opened (GdmManager         *manager,
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL,
                                            cancellable,
-                                           (GAsyncReadyCallback)
                                            on_reauthentication_channel_connected,
-                                           task);
+                                           g_steal_pointer (&task));
 }
 
 static void
 on_got_manager_for_reauthentication (GdmClient           *client,
                                      GAsyncResult        *result,
-                                     GTask               *task)
+                                     gpointer             user_data)
 {
         GCancellable *cancellable;
-        GdmManager   *manager;
-        char         *username;
-        GError       *error;
+        const char   *username;
+        g_autoptr(GTask)      task = user_data;
+        g_autoptr(GdmManager) manager = NULL;
+        g_autoptr(GError)     error = NULL;
 
-        error = NULL;
         manager = g_task_propagate_pointer (G_TASK (result), &error);
         if (manager == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -409,8 +394,7 @@ on_got_manager_for_reauthentication (GdmClient           *client,
                                                         cancellable,
                                                         (GAsyncReadyCallback)
                                                         on_reauthentication_channel_opened,
-                                                        task);
-        g_object_unref (manager);
+                                                        g_steal_pointer (&task));
 }
 
 static GDBusConnection *
@@ -465,46 +449,41 @@ gdm_client_get_connection_sync (GdmClient      *client,
 static void
 on_connected (GObject            *source_object,
               GAsyncResult       *result,
-              GTask              *task)
+              gpointer            user_data)
 {
-        GDBusConnection *connection;
-        GError *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = g_dbus_connection_new_for_address_finish (result, &error);
         if (!connection) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
         g_task_return_pointer (task,
-                               g_object_ref (connection),
+                               g_steal_pointer (&connection),
                                (GDestroyNotify) g_object_unref);
-        g_object_unref (task);
-        g_object_unref (connection);
 }
 
 static void
 on_session_opened (GdmManager         *manager,
                    GAsyncResult       *result,
-                   GTask              *task)
+                   gpointer            user_data)
 {
-        GdmClient *client;
-        g_autofree char  *address = NULL;
         GCancellable     *cancellable;
-        GError           *error;
+        g_autoptr(GTask)     task = user_data;
+        g_autoptr(GdmClient) client = NULL;
+        g_autoptr(GError)    error = NULL;
+        g_autofree char     *address = NULL;
 
         client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (task)));
 
-        error = NULL;
         if (!gdm_manager_call_open_session_finish (manager,
                                                    &address,
                                                    result,
                                                    &error)) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
-                g_object_unref (client);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -513,26 +492,23 @@ on_session_opened (GdmManager         *manager,
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL,
                                            cancellable,
-                                           (GAsyncReadyCallback)
                                            on_connected,
-                                           task);
-        g_object_unref (client);
+                                           g_steal_pointer (&task));
 }
 
 static void
 on_got_manager_for_opening_connection (GdmClient           *client,
                                        GAsyncResult        *result,
-                                       GTask               *task)
+                                       gpointer             user_data)
 {
         GCancellable *cancellable;
-        GdmManager   *manager;
-        GError       *error;
+        g_autoptr(GTask)      task = user_data;
+        g_autoptr(GdmManager) manager = NULL;
+        g_autoptr(GError)     error = NULL;
 
-        error = NULL;
         manager = g_task_propagate_pointer (G_TASK (result), &error);
         if (manager == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -541,9 +517,7 @@ on_got_manager_for_opening_connection (GdmClient           *client,
                                        cancellable,
                                        (GAsyncReadyCallback)
                                        on_session_opened,
-                                       task);
-
-        g_object_unref (manager);
+                                       g_steal_pointer (&task));
 }
 
 static GDBusConnection *
@@ -569,7 +543,7 @@ gdm_client_get_connection (GdmClient           *client,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
 {
-        GTask *task;
+        g_autoptr(GTask) task = NULL;
         GDBusConnection *connection;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
@@ -584,7 +558,6 @@ gdm_client_get_connection (GdmClient           *client,
             g_task_return_pointer (task,
                                    g_object_ref (connection),
                                    (GDestroyNotify) g_object_unref);
-            g_object_unref (task);
             return;
         }
 
@@ -592,7 +565,7 @@ gdm_client_get_connection (GdmClient           *client,
                      cancellable,
                      (GAsyncReadyCallback)
                      on_got_manager_for_opening_connection,
-                     task);
+                     g_steal_pointer (&task));
 }
 
 /**
@@ -616,7 +589,7 @@ gdm_client_open_reauthentication_channel_sync (GdmClient     *client,
                                                GError       **error)
 {
         g_autoptr(GDBusConnection) connection = NULL;
-        g_autoptr(GdmManager) manager = NULL;
+        g_autoptr(GdmManager)      manager = NULL;
         g_autofree char *address = NULL;
         GdmUserVerifier *user_verifier = NULL;
         gboolean         ret;
@@ -806,18 +779,16 @@ gdm_client_get_user_verifier_sync (GdmClient     *client,
 static void
 on_connection_for_user_verifier (GdmClient          *client,
                                  GAsyncResult       *result,
-                                 GTask              *task)
+                                 gpointer            user_data)
 {
-        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
-        GError       *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = gdm_client_get_connection_finish (client, result, &error);
-
         if (connection == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -827,9 +798,8 @@ on_connection_for_user_verifier (GdmClient          *client,
                                      NULL,
                                      SESSION_DBUS_PATH,
                                      cancellable,
-                                     (GAsyncReadyCallback)
                                      on_user_verifier_proxy_created,
-                                     task);
+                                     g_steal_pointer (&task));
 }
 
 /**
@@ -848,7 +818,7 @@ gdm_client_get_user_verifier (GdmClient           *client,
                               GAsyncReadyCallback  callback,
                               gpointer             user_data)
 {
-        GTask *task;
+        g_autoptr(GTask) task = NULL;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
@@ -861,15 +831,14 @@ gdm_client_get_user_verifier (GdmClient           *client,
                 g_task_return_pointer (task,
                                        g_object_ref (client->priv->user_verifier),
                                        (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
                 return;
         }
 
         gdm_client_get_connection (client,
-                                    cancellable,
-                                    (GAsyncReadyCallback)
-                                    on_connection_for_user_verifier,
-                                    task);
+                                   cancellable,
+                                   (GAsyncReadyCallback)
+                                   on_connection_for_user_verifier,
+                                   g_steal_pointer (&task));
 }
 
 /**
@@ -951,22 +920,21 @@ query_for_timed_login_requested_signal (GdmGreeter *greeter)
 static void
 on_greeter_proxy_created (GObject            *source,
                           GAsyncResult       *result,
-                          GTask              *task)
+                          gpointer            user_data)
 {
+        g_autoptr(GTask)  task = user_data;
+        g_autoptr(GError) error = NULL;
         GdmGreeter   *greeter;
-        GError       *error = NULL;
 
         greeter = gdm_greeter_proxy_new_finish (result, &error);
         if (greeter == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
         g_task_return_pointer (task,
                                greeter,
                                (GDestroyNotify) g_object_unref);
-        g_object_unref (task);
 
         query_for_timed_login_requested_signal (greeter);
 }
@@ -974,18 +942,17 @@ on_greeter_proxy_created (GObject            *source,
 static void
 on_connection_for_greeter (GdmClient          *client,
                            GAsyncResult       *result,
-                           GTask              *task)
+                           gpointer            user_data)
 {
-        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
-        GError       *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = gdm_client_get_connection_finish (client, result, &error);
 
         if (connection == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -995,9 +962,8 @@ on_connection_for_greeter (GdmClient          *client,
                                NULL,
                                SESSION_DBUS_PATH,
                                cancellable,
-                               (GAsyncReadyCallback)
                                on_greeter_proxy_created,
-                               task);
+                               g_steal_pointer (&task));
 }
 
 /**
@@ -1016,7 +982,7 @@ gdm_client_get_greeter (GdmClient           *client,
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
 {
-        GTask *task;
+        g_autoptr(GTask) task = NULL;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
@@ -1029,15 +995,14 @@ gdm_client_get_greeter (GdmClient           *client,
                 g_task_return_pointer (task,
                                        g_object_ref (client->priv->greeter),
                                        (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
                 return;
         }
 
         gdm_client_get_connection (client,
-                                    cancellable,
-                                    (GAsyncReadyCallback)
-                                    on_connection_for_greeter,
-                                    task);
+                                   cancellable,
+                                   (GAsyncReadyCallback)
+                                   on_connection_for_greeter,
+                                   g_steal_pointer (&task));
 }
 
 /**
@@ -1127,39 +1092,37 @@ gdm_client_get_greeter_sync (GdmClient     *client,
 static void
 on_remote_greeter_proxy_created (GObject            *object,
                                  GAsyncResult       *result,
-                                 GTask              *task)
+                                 gpointer            user_data)
 {
+        g_autoptr(GTask)  task = user_data;
+        g_autoptr(GError) error = NULL;
         GdmRemoteGreeter *remote_greeter;
-        GError           *error = NULL;
 
         remote_greeter = gdm_remote_greeter_proxy_new_finish (result, &error);
         if (remote_greeter == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
         g_task_return_pointer (task,
                                remote_greeter,
                                (GDestroyNotify) g_object_unref);
-        g_object_unref (task);
 }
 
 static void
 on_connection_for_remote_greeter (GdmClient          *client,
                                   GAsyncResult       *result,
-                                  GTask              *task)
+                                  gpointer            user_data)
 {
-        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
-        GError       *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = gdm_client_get_connection_finish (client, result, &error);
 
         if (connection == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -1169,9 +1132,8 @@ on_connection_for_remote_greeter (GdmClient          *client,
                                       NULL,
                                       SESSION_DBUS_PATH,
                                       cancellable,
-                                      (GAsyncReadyCallback)
                                       on_remote_greeter_proxy_created,
-                                      task);
+                                      g_steal_pointer (&task));
 }
 
 /**
@@ -1190,7 +1152,7 @@ gdm_client_get_remote_greeter (GdmClient           *client,
                                GAsyncReadyCallback  callback,
                                gpointer             user_data)
 {
-        GTask *task;
+        g_autoptr (GTask) task = NULL;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
@@ -1203,15 +1165,14 @@ gdm_client_get_remote_greeter (GdmClient           *client,
                 g_task_return_pointer (task,
                                        g_object_ref (client->priv->remote_greeter),
                                        (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
                 return;
         }
 
         gdm_client_get_connection (client,
-                                    cancellable,
-                                    (GAsyncReadyCallback)
-                                    on_connection_for_remote_greeter,
-                                    task);
+                                   cancellable,
+                                   (GAsyncReadyCallback)
+                                   on_connection_for_remote_greeter,
+                                   g_steal_pointer (&task));
 }
 
 /**
@@ -1298,39 +1259,37 @@ gdm_client_get_remote_greeter_sync (GdmClient     *client,
 static void
 on_chooser_proxy_created (GObject            *source,
                           GAsyncResult       *result,
-                          GTask              *task)
+                          gpointer            user_data)
 {
         GdmChooser   *chooser;
-        GError       *error = NULL;
+        g_autoptr(GTask)  task = user_data;
+        g_autoptr(GError) error = NULL;
 
         chooser = gdm_chooser_proxy_new_finish (result, &error);
         if (chooser == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
         g_task_return_pointer (task,
                                chooser,
                                (GDestroyNotify) g_object_unref);
-        g_object_unref (task);
 }
 
 static void
 on_connection_for_chooser (GdmClient          *client,
                            GAsyncResult       *result,
-                           GTask              *task)
+                           gpointer            user_data)
 {
-        g_autoptr(GDBusConnection) connection = NULL;
         GCancellable *cancellable;
-        GError       *error;
+        g_autoptr(GTask)           task = user_data;
+        g_autoptr(GDBusConnection) connection = NULL;
+        g_autoptr(GError)          error = NULL;
 
-        error = NULL;
         connection = gdm_client_get_connection_finish (client, result, &error);
 
         if (connection == NULL) {
-                g_task_return_error (task, error);
-                g_object_unref (task);
+                g_task_return_error (task, g_steal_pointer (&error));
                 return;
         }
 
@@ -1342,7 +1301,7 @@ on_connection_for_chooser (GdmClient          *client,
                                cancellable,
                                (GAsyncReadyCallback)
                                on_chooser_proxy_created,
-                               task);
+                               g_steal_pointer (&task));
 }
 
 /**
@@ -1361,7 +1320,7 @@ gdm_client_get_chooser (GdmClient           *client,
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
 {
-        GTask *task;
+        g_autoptr(GTask) task = NULL;
 
         g_return_if_fail (GDM_IS_CLIENT (client));
 
@@ -1374,15 +1333,14 @@ gdm_client_get_chooser (GdmClient           *client,
                 g_task_return_pointer (task,
                                        g_object_ref (client->priv->chooser),
                                        (GDestroyNotify) g_object_unref);
-                g_object_unref (task);
                 return;
         }
 
         gdm_client_get_connection (client,
-                                    cancellable,
-                                    (GAsyncReadyCallback)
-                                    on_connection_for_chooser,
-                                    task);
+                                   cancellable,
+                                   (GAsyncReadyCallback)
+                                   on_connection_for_chooser,
+                                   g_steal_pointer (&task));
 }
 
 /**
-- 
2.32.0

