summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <[email protected]>2011-09-09 09:54:14 +0200
committerVictor Kareh <[email protected]>2019-02-04 07:52:05 -0500
commit409d9fcc735f6dfd6ada9d90360e045130379259 (patch)
tree831e37e9589e3ab1edef800ff4bdd04b5744208f
parent0f4afbbdef79ce391455d246d62b403b6d0046f1 (diff)
downloadmate-session-manager-409d9fcc735f6dfd6ada9d90360e045130379259.tar.bz2
mate-session-manager-409d9fcc735f6dfd6ada9d90360e045130379259.tar.xz
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 Adapted from https://gitlab.gnome.org/GNOME/gnome-session/commit/ae8fa537
-rw-r--r--mate-session/gsm-manager.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/mate-session/gsm-manager.c b/mate-session/gsm-manager.c
index 816a0e9..3ffcbf3 100644
--- a/mate-session/gsm-manager.c
+++ b/mate-session/gsm-manager.c
@@ -146,6 +146,7 @@ typedef struct {
DBusGProxy *bus_proxy;
DBusGConnection *connection;
+ gboolean dbus_disconnected : 1;
} GsmManagerPrivate;
enum {
@@ -1798,6 +1799,12 @@ _disconnect_client (GsmManager *manager,
"phase");
}
+ if (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;
@@ -1852,6 +1859,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;
@@ -1865,6 +1878,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)
@@ -1952,11 +1974,36 @@ bus_name_owner_changed (DBusGProxy *bus_proxy,
}
}
+static DBusHandlerResult
+gsm_manager_bus_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ GsmManager *manager;
+ GsmManagerPrivate *priv;
+
+ manager = GSM_MANAGER (user_data);
+ priv = gsm_manager_get_instance_private (manager);
+
+ 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...");
+ 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;
GsmManagerPrivate *priv;
+ DBusConnection *connection;
error = NULL;
priv = gsm_manager_get_instance_private (manager);
@@ -1970,6 +2017,12 @@ register_manager (GsmManager *manager)
exit (1);
}
+ connection = dbus_g_connection_get_connection (priv->connection);
+ dbus_connection_add_filter (connection,
+ gsm_manager_bus_filter,
+ manager, NULL);
+ priv->dbus_disconnected = FALSE;
+
priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,