From ebd24abc59b18c09fb21905945e57c03a02caca6 Mon Sep 17 00:00:00 2001
From: Joan Torres <joan.torres@suse.com>
Date: Wed, 11 Dec 2024 15:29:17 +0100
Subject: [PATCH 1/2] sharing: Stop assigned services properly on manager stop

Assigned services are started when sharing status is not offline.
But they were being stopped only when status is available.
To fix this, stop assigned services when status is not offline too.

This doesn't affect configurable services which weren't already started.
---
 plugins/sharing/gsd-sharing-manager.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plugins/sharing/gsd-sharing-manager.c b/plugins/sharing/gsd-sharing-manager.c
index 40b2bcc51..26e31da05 100644
--- a/plugins/sharing/gsd-sharing-manager.c
+++ b/plugins/sharing/gsd-sharing-manager.c
@@ -953,7 +953,7 @@ gsd_sharing_manager_shutdown (GApplication *app)
 
         cancel_pending_wait_tasks (manager);
 
-        if (manager->sharing_status == GSD_SHARING_STATUS_AVAILABLE &&
+        if (manager->sharing_status != GSD_SHARING_STATUS_OFFLINE &&
             manager->connection != NULL) {
                 manager->sharing_status = GSD_SHARING_STATUS_OFFLINE;
                 gsd_sharing_manager_sync_services (manager);
-- 
GitLab


From d0b0d3a6971f0174c873c45ae20b5bf3bd91481b Mon Sep 17 00:00:00 2001
From: Joan Torres <joan.torres@suse.com>
Date: Tue, 14 Jan 2025 19:20:10 +0100
Subject: [PATCH 2/2] sharing: Wait for async service operations during
 shutdown

Make a synchronization mechanism using a counter and a main loop.

This ensures that all systemd service operations are properly handled
before the sharing manager is fully stopped, preventing services from
being left in an inconsistent state.

This fixes an issue where the gnome-remote-desktop-handover.service was
not stopped on logout. Making the next user session use the same
handover daemon which is still listening to the old handover iface with
the old session id.
---
 plugins/sharing/gsd-sharing-manager.c | 29 ++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/plugins/sharing/gsd-sharing-manager.c b/plugins/sharing/gsd-sharing-manager.c
index 26e31da05..9e44bd2c6 100644
--- a/plugins/sharing/gsd-sharing-manager.c
+++ b/plugins/sharing/gsd-sharing-manager.c
@@ -83,6 +83,9 @@ struct _GsdSharingManager
         GsdSharingStatus         sharing_status;
 
         gboolean                 is_systemd_managed;
+
+        guint                    pending_sync_services;
+        GMainLoop               *wait_sync_services_loop;
 };
 
 #define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
@@ -147,9 +150,9 @@ handle_unit_cb (GObject      *source_object,
                 GAsyncResult *res,
                 gpointer      user_data)
 {
-        GError *error = NULL;
-        GVariant *ret;
-        const char *operation = user_data;
+        g_autoptr (GError) error = NULL;
+        g_autoptr (GVariant) ret = NULL;
+        GsdSharingManager *manager = user_data;
 
         ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
                                              res, &error);
@@ -158,13 +161,13 @@ handle_unit_cb (GObject      *source_object,
 
                 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
                     g_strcmp0 (remote_error, "org.freedesktop.systemd1.NoSuchUnit") != 0)
-                        g_warning ("Failed to %s service: %s", operation, error->message);
-                g_error_free (error);
-                return;
+                        g_warning ("Failed to handle service: %s", error->message);
         }
 
-        g_variant_unref (ret);
-
+        manager->pending_sync_services--;
+        if (manager->pending_sync_services == 0 && manager->wait_sync_services_loop) {
+                g_main_loop_quit (manager->wait_sync_services_loop);
+        }
 }
 
 static void
@@ -174,6 +177,8 @@ gsd_sharing_manager_handle_service (GsdSharingManager   *manager,
 {
         char *service_file;
 
+        manager->pending_sync_services++;
+
         service_file = g_strdup_printf ("%s.service", service_name);
         g_dbus_connection_call (manager->connection,
                                 "org.freedesktop.systemd1",
@@ -186,7 +191,7 @@ gsd_sharing_manager_handle_service (GsdSharingManager   *manager,
                                 -1,
                                 manager->cancellable,
                                 handle_unit_cb,
-                                (gpointer) method);
+                                (gpointer) manager);
         g_free (service_file);
 }
 
@@ -959,6 +964,12 @@ gsd_sharing_manager_shutdown (GApplication *app)
                 gsd_sharing_manager_sync_services (manager);
         }
 
+        if (manager->pending_sync_services > 0) {
+                manager->wait_sync_services_loop = g_main_loop_new (NULL, FALSE);
+                g_main_loop_run (manager->wait_sync_services_loop);
+                g_clear_pointer (&manager->wait_sync_services_loop, g_main_loop_unref);
+        }
+
         if (manager->cancellable) {
                 g_cancellable_cancel (manager->cancellable);
                 g_clear_object (&manager->cancellable);
-- 
GitLab

