[gnome-session] gsm: Disconnect all dbus clients when dbus is disconnected



commit ae8fa537262d6bec9c7eaa5a963cba98ec4e2136
Author: Vincent Untz <vuntz gnome org>
Date:   Fri Sep 9 09:54:14 2011 +0200

    gsm: Disconnect all dbus clients when dbus is disconnected
    
    When we receive the Disconnected signal from dbus on the session bus,
    then we know we won't be able to talk to dbus clients anymore, so mark
    them as disconnected. Also, do not restart them even if they're supposed
    to be autorestarted, as we won't be able to track them.
    
    At this point, the session is kind of hosed. We could possibly decide
    to simply leave, but we don't do it in case it's a user session and
    there's unsaved data.
    
    This helps a lot in the case of the gdm greeter, see
    https://bugzilla.gnome.org/show_bug.cgi?id=658481

 gnome-session/gsm-manager.c |   49 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)
---
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index b531197..2d74d40 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -151,6 +151,7 @@ struct GsmManagerPrivate
 
         DBusGProxy             *bus_proxy;
         DBusGConnection        *connection;
+        gboolean                dbus_disconnected : 1;
 
         /* Interface with other parts of the system */
         UpClient               *up_client;
@@ -1814,6 +1815,11 @@ _disconnect_client (GsmManager *manager,
                                                      "phase");
         }
 
+        if (manager->priv->dbus_disconnected && GSM_IS_DBUS_CLIENT (client)) {
+                g_debug ("GsmManager: dbus disconnected, not restarting application");
+                goto out;
+        }
+
         if (app == NULL) {
                 g_debug ("GsmManager: unable to find application for client - not restarting");
                 goto out;
@@ -1872,6 +1878,12 @@ _disconnect_dbus_client (const char       *id,
                 return FALSE;
         }
 
+        /* If no service name, then we simply disconnect all clients */
+        if (!data->service_name) {
+                _disconnect_client (data->manager, client);
+                return TRUE;
+        }
+
         name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
         if (IS_STRING_EMPTY (name)) {
                 return FALSE;
@@ -1885,6 +1897,15 @@ _disconnect_dbus_client (const char       *id,
         return FALSE;
 }
 
+/**
+ * remove_clients_for_connection:
+ * @manager: a #GsmManager
+ * @service_name: a service name
+ *
+ * Disconnects clients that own @service_name.
+ *
+ * If @service_name is NULL, then disconnects all clients for the connection.
+ */
 static void
 remove_clients_for_connection (GsmManager *manager,
                                const char *service_name)
@@ -1968,10 +1989,32 @@ bus_name_owner_changed (DBusGProxy  *bus_proxy,
         }
 }
 
+static DBusHandlerResult
+gsm_manager_bus_filter (DBusConnection *connection,
+                        DBusMessage    *message,
+                        void           *user_data)
+{
+        GsmManager *manager;
+
+        manager = GSM_MANAGER (user_data);
+
+        if (dbus_message_is_signal (message,
+                                    DBUS_INTERFACE_LOCAL, "Disconnected") &&
+            strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
+                g_debug ("GsmManager: dbus disconnected; disconnecting dbus clients...");
+                manager->priv->dbus_disconnected = TRUE;
+                remove_clients_for_connection (manager, NULL);
+                /* let other filters get this disconnected signal, so that they
+                 * can handle it too */
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
 static gboolean
 register_manager (GsmManager *manager)
 {
         GError *error = NULL;
+        DBusConnection *connection;
 
         error = NULL;
         manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
@@ -1983,6 +2026,12 @@ register_manager (GsmManager *manager)
                 exit (1);
         }
 
+        connection = dbus_g_connection_get_connection (manager->priv->connection);
+        dbus_connection_add_filter (connection,
+                                    gsm_manager_bus_filter,
+                                    manager, NULL);
+        manager->priv->dbus_disconnected = FALSE;
+
         manager->priv->bus_proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
                                                               DBUS_SERVICE_DBUS,
                                                               DBUS_PATH_DBUS,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]