From 9af0e74bd81e8d924cb07a5452c068cc1403e9bf Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 17 May 2013 09:35:18 -0400
Subject: [PATCH] manager: don't try to unexport objects on system bus after it
 closes

When the main GDM manager object is finalized, it unexports any
exported DBus ObjectManager objects.

In many cases, the system bus is no longer around by the time the GDM
manager object is finalized.  Unexporting an object when the the
bus connection is already closed will make GDBus blow an assertion
(since it's already been implicitly unexported by virtue of being
disconnected).

This commit changes the GDM manager object's finalize method to avoid
explicitly unexporting the objects in the above scenario.

https://bugzilla.gnome.org/show_bug.cgi?id=700523
---
 daemon/gdm-manager.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 6e1eaba..8a8fcf2 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1145,46 +1145,48 @@ gdm_manager_finalize (GObject *object)
 
         g_return_if_fail (object != NULL);
         g_return_if_fail (GDM_IS_MANAGER (object));
 
         manager = GDM_MANAGER (object);
 
         g_return_if_fail (manager->priv != NULL);
 
 #ifdef HAVE_LIBXDMCP
         g_clear_object (&manager->priv->xdmcp_factory);
 #endif
         g_clear_object (&manager->priv->local_factory);
 
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
                                               G_CALLBACK (on_display_added),
                                               manager);
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
                                               G_CALLBACK (on_display_removed),
                                               manager);
 
-        gdm_display_store_foreach (manager->priv->display_store,
-                                   (GdmDisplayStoreFunc)unexport_display,
-                                   manager);
-        gdm_display_store_clear (manager->priv->display_store);
+        if (!g_dbus_connection_is_closed (manager->priv->connection)) {
+                gdm_display_store_foreach (manager->priv->display_store,
+                                           (GdmDisplayStoreFunc)unexport_display,
+                                           manager);
+                g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
+        }
 
-        g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
+        gdm_display_store_clear (manager->priv->display_store);
 
         g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
 
         g_clear_object (&manager->priv->connection);
         g_clear_object (&manager->priv->object_manager);
 
         g_object_unref (manager->priv->display_store);
 
         G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object);
 }
 
 GdmManager *
 gdm_manager_new (void)
 {
         if (manager_object != NULL) {
                 g_object_ref (manager_object);
         } else {
                 gboolean res;
 
                 manager_object = g_object_new (GDM_TYPE_MANAGER, NULL);
-- 
1.8.2.1