Skip to content
Browse files

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
Adapted from
  • Loading branch information...
vuntz authored and vkareh committed Sep 9, 2011
1 parent 0f4afbb commit 409d9fcc735f6dfd6ada9d90360e045130379259
Showing with 53 additions and 0 deletions.
  1. +53 −0 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,

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 */


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,
manager, NULL);
priv->dbus_disconnected = FALSE;

priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,

0 comments on commit 409d9fc

Please sign in to comment.
You can’t perform that action at this time.