[gnome-session] manager: get rid of global NameOwnerChanged handler



commit 79ab4f2fe0f36dc86e96d19dd10ff14b47b04050
Author: Ray Strode <rstrode redhat com>
Date:   Thu Mar 3 10:50:45 2016 -0500

    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

 gnome-session/gsm-dbus-client.c |   23 +++++++++++++++++
 gnome-session/gsm-inhibitor.c   |   39 ++++++++++++++++++++++++++++
 gnome-session/gsm-manager.c     |   53 ++++++--------------------------------
 3 files changed, 71 insertions(+), 44 deletions(-)
---
diff --git a/gnome-session/gsm-dbus-client.c b/gnome-session/gsm-dbus-client.c
index e4609d5..598df4e 100644
--- a/gnome-session/gsm-dbus-client.c
+++ b/gnome-session/gsm-dbus-client.c
@@ -47,6 +47,7 @@ struct GsmDBusClientPrivate
 
         GDBusConnection      *connection;
         GsmExportedClientPrivate *skeleton;
+        guint                 watch_id;
 };
 
 enum {
@@ -219,6 +220,17 @@ out:
 }
 
 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);
 }
 
diff --git a/gnome-session/gsm-inhibitor.c b/gnome-session/gsm-inhibitor.c
index 05e3df7..3f02148 100644
--- a/gnome-session/gsm-inhibitor.c
+++ b/gnome-session/gsm-inhibitor.c
@@ -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"
@@ -236,6 +244,18 @@ gsm_inhibitor_init (GsmInhibitor *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",
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 298253e..6e18f31 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -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;
@@ -2163,6 +2162,13 @@ update_inhibited_actions (GsmManager *manager,
 }
 
 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,
                           GsmManager *manager)
@@ -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;
 


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