Commit 79ab4f2f authored by Ray Strode's avatar Ray Strode

manager: get rid of global NameOwnerChanged handler

Listening for NameOwnerChanged on the bus is costly, since it means
waking up basically any time any program is started or exists.

This commit changes the code to instead create individual watches,
instead of one global watch.

https://bugzilla.gnome.org/show_bug.cgi?id=753309
parent 837f237c
......@@ -47,6 +47,7 @@ struct GsmDBusClientPrivate
GDBusConnection *connection;
GsmExportedClientPrivate *skeleton;
guint watch_id;
};
enum {
......@@ -218,6 +219,17 @@ out:
return retval;
}
static void
on_client_vanished (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
GsmDBusClient *client = user_data;
gsm_client_disconnected (GSM_CLIENT (client));
g_bus_unwatch_name (client->priv->watch_id);
}
static void
gsm_dbus_client_set_bus_name (GsmDBusClient *client,
const char *bus_name)
......@@ -232,6 +244,14 @@ gsm_dbus_client_set_bus_name (GsmDBusClient *client,
if (!get_caller_info (client, bus_name, NULL, &client->priv->caller_pid)) {
client->priv->caller_pid = 0;
}
client->priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
bus_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL,
on_client_vanished,
client,
NULL);
}
const char *
......@@ -297,6 +317,9 @@ gsm_dbus_client_finalize (GObject *object)
g_clear_object (&client->priv->connection);
if (client->priv->watch_id != 0)
g_bus_unwatch_name (client->priv->watch_id);
G_OBJECT_CLASS (gsm_dbus_client_parent_class)->finalize (object);
}
......
......@@ -45,6 +45,8 @@ struct GsmInhibitorPrivate
guint cookie;
GDBusConnection *connection;
GsmExportedInhibitor *skeleton;
guint watch_id;
};
enum {
......@@ -58,6 +60,12 @@ enum {
PROP_COOKIE
};
enum {
VANISHED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GsmInhibitor, gsm_inhibitor, G_TYPE_OBJECT)
#define GSM_INHIBITOR_DBUS_IFACE "org.gnome.SessionManager.Inhibitor"
......@@ -235,6 +243,18 @@ gsm_inhibitor_init (GsmInhibitor *inhibitor)
inhibitor->priv = GSM_INHIBITOR_GET_PRIVATE (inhibitor);
}
static void
on_inhibitor_vanished (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
GsmInhibitor *inhibitor = user_data;
g_signal_emit (inhibitor, signals[VANISHED], 0);
g_bus_unwatch_name (inhibitor->priv->watch_id);
}
static void
gsm_inhibitor_set_bus_name (GsmInhibitor *inhibitor,
const char *bus_name)
......@@ -245,6 +265,14 @@ gsm_inhibitor_set_bus_name (GsmInhibitor *inhibitor,
if (bus_name != NULL) {
inhibitor->priv->bus_name = g_strdup (bus_name);
inhibitor->priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
bus_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL,
on_inhibitor_vanished,
inhibitor,
NULL);
} else {
inhibitor->priv->bus_name = g_strdup ("");
}
......@@ -490,6 +518,10 @@ gsm_inhibitor_finalize (GObject *object)
g_clear_object (&inhibitor->priv->skeleton);
}
if (inhibitor->priv->watch_id != 0) {
g_bus_unwatch_name (inhibitor->priv->watch_id);
}
g_clear_object (&inhibitor->priv->connection);
G_OBJECT_CLASS (gsm_inhibitor_parent_class)->finalize (object);
......@@ -505,6 +537,13 @@ gsm_inhibitor_class_init (GsmInhibitorClass *klass)
object_class->get_property = gsm_inhibitor_get_property;
object_class->set_property = gsm_inhibitor_set_property;
signals[VANISHED] =
g_signal_new ("vanished",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE,
0);
g_object_class_install_property (object_class,
PROP_BUS_NAME,
g_param_spec_string ("bus-name",
......
......@@ -158,7 +158,6 @@ struct GsmManagerPrivate
GDBusConnection *connection;
GsmExportedManager *skeleton;
gboolean dbus_disconnected : 1;
guint name_owner_id;
GsmShell *shell;
guint shell_end_session_dialog_canceled_id;
......@@ -2162,6 +2161,13 @@ update_inhibited_actions (GsmManager *manager,
manager->priv->inhibited_actions);
}
static void
on_inhibitor_vanished (GsmInhibitor *inhibitor,
GsmManager *manager)
{
gsm_store_remove (manager->priv->inhibitors, gsm_inhibitor_peek_id (inhibitor));
}
static void
on_store_inhibitor_added (GsmStore *store,
const char *id,
......@@ -2179,6 +2185,8 @@ on_store_inhibitor_added (GsmStore *store,
new_inhibited_actions = manager->priv->inhibited_actions | gsm_inhibitor_peek_flags (i);
update_inhibited_actions (manager, new_inhibited_actions);
g_signal_connect_object (i, "vanished", G_CALLBACK (on_inhibitor_vanished), manager, 0);
gsm_exported_manager_emit_inhibitor_added (manager->priv->skeleton, id);
update_idle (manager);
......@@ -2263,11 +2271,6 @@ gsm_manager_dispose (GObject *object)
g_clear_object (&manager->priv->system);
g_clear_object (&manager->priv->shell);
if (manager->priv->name_owner_id != 0) {
g_dbus_connection_signal_unsubscribe (manager->priv->connection, manager->priv->name_owner_id);;
manager->priv->name_owner_id = 0;
}
if (manager->priv->skeleton != NULL) {
g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (manager->priv->skeleton),
manager->priv->connection);
......@@ -3116,34 +3119,6 @@ remove_inhibitors_for_connection (GsmManager *manager,
}
}
static void
bus_name_owner_changed (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
GsmManager *manager = user_data;
const gchar *service_name, *old_service_name, *new_service_name;
g_variant_get (parameters, "(&s&s&s)", &service_name, &old_service_name, &new_service_name);
if (strlen (new_service_name) == 0
&& strlen (old_service_name) > 0) {
/* service removed */
remove_inhibitors_for_connection (manager, old_service_name);
remove_clients_for_connection (manager, old_service_name);
} else if (strlen (old_service_name) == 0
&& strlen (new_service_name) > 0) {
/* service added */
/* use this if we support automatically registering
* well known bus names */
}
}
static gboolean
register_manager (GsmManager *manager)
{
......@@ -3209,16 +3184,6 @@ register_manager (GsmManager *manager)
g_signal_connect (connection, "closed",
G_CALLBACK (on_session_connection_closed), manager);
manager->priv->name_owner_id = g_dbus_connection_signal_subscribe (connection,
"org.freedesktop.DBus",
"org.freedesktop.DBus",
"NameOwnerChanged",
"/org/freedesktop/DBus",
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
bus_name_owner_changed,
manager,
NULL);
manager->priv->connection = connection;
manager->priv->skeleton = skeleton;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment