[gdm] Load sessions asynchronously at startup



commit b987d7cff0b8a2c680bca14a73a565872f61eacc
Author: Ray Strode <rstrode redhat com>
Date:   Wed Jun 23 22:30:02 2010 -0400

    Load sessions asynchronously at startup
    
    In an effort to minimize blocking calls in the "hot path"
    (namely start up), this commit makes gdm invoke
    the ConsoleKit GetSessions call asynchronously.
    
    This change implies a slight semantic shift in the way the code
    works.  Previously, it was guaranteed that all sessions were
    loaded before the ck history file and passwd file were parsed.
    
    Now, all the three tasks are asynchronous and race with each other.
    
    This is "okay" to do because the code already allows sessions
    to get added to existing users, and users to get created for
    existing sessions.
    
    There is still one GetSessions call that is synchronous.  This call is
    during the middle of a user switch, so it's less critical.
    
    These changes only effect the non-accounts-service code path.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=622639
    (cherry picked from commit f13e6afc43a8008c9d1bc86a1e64d54cc221d3b0)

 gui/simple-greeter/gdm-user-manager.c |   87 +++++++++++++++++++++++++--------
 1 files changed, 66 insertions(+), 21 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index 48b7fc5..ce65804 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -56,6 +56,8 @@
 #define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
 #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
 
+#define GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
+
 /* Prefs Defaults */
 
 #ifdef __sun
@@ -90,6 +92,7 @@ struct GdmUserManagerPrivate
         GHashTable            *shells;
         DBusGConnection       *connection;
         DBusGProxy            *seat_proxy;
+        DBusGProxyCall        *get_sessions_call;
         DBusGProxy            *accounts_proxy;
         char                  *seat_id;
 
@@ -1364,6 +1367,10 @@ maybe_set_is_loaded (GdmUserManager *manager)
                 return;
         }
 
+        if (manager->priv->get_sessions_call != NULL) {
+                return;
+        }
+
         set_is_loaded (manager, TRUE);
 }
 
@@ -1839,26 +1846,40 @@ schedule_reload_passwd (GdmUserManager *manager)
 }
 
 static void
-load_sessions (GdmUserManager *manager)
+load_sessions_from_array (GdmUserManager     *manager,
+                          const char * const *session_ids,
+                          int                 number_of_sessions)
 {
-        gboolean    res;
-        GError     *error;
-        GPtrArray  *sessions;
-        int         i;
+        int i;
 
-        if (manager->priv->seat_proxy == NULL) {
-                g_debug ("GdmUserManager: no seat proxy; can't load sessions");
-                return;
+        for (i = 0; i < number_of_sessions; i++) {
+                maybe_add_session (manager, session_ids[i]);
         }
+}
+
+static void
+on_get_sessions_finished (DBusGProxy     *proxy,
+                          DBusGProxyCall *call,
+                          gpointer        data)
+{
+        GdmUserManager *manager;
+        GError         *error;
+        gboolean        res;
+        GPtrArray      *sessions;
+
+        manager = GDM_USER_MANAGER (data);
+
+        g_assert (manager->priv->get_sessions_call == call);
 
-        sessions = NULL;
         error = NULL;
-        res = dbus_g_proxy_call (manager->priv->seat_proxy,
-                                 "GetSessions",
-                                 &error,
-                                 G_TYPE_INVALID,
-                                 dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions,
-                                 G_TYPE_INVALID);
+        sessions = NULL;
+        res = dbus_g_proxy_end_call (proxy,
+                                     call,
+                                     &error,
+                                     GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY,
+                                     &sessions,
+                                     G_TYPE_INVALID);
+
         if (! res) {
                 if (error != NULL) {
                         g_warning ("unable to determine sessions for seat: %s",
@@ -1870,15 +1891,39 @@ load_sessions (GdmUserManager *manager)
                 return;
         }
 
-        for (i = 0; i < sessions->len; i++) {
-                char *ssid;
+        manager->priv->get_sessions_call = NULL;
+        g_assert (sessions->len <= G_MAXINT);
+        load_sessions_from_array (manager,
+                                  (const char * const *) sessions->pdata,
+                                  (int) sessions->len);
+        g_ptr_array_foreach (sessions, (GFunc) g_free, NULL);
+        g_ptr_array_free (sessions, TRUE);
+        maybe_set_is_loaded (manager);
+}
 
-                ssid = g_ptr_array_index (sessions, i);
+static void
+load_sessions (GdmUserManager *manager)
+{
+        DBusGProxyCall *call;
 
-                maybe_add_session (manager, ssid);
+        if (manager->priv->seat_proxy == NULL) {
+                g_debug ("GdmUserManager: no seat proxy; can't load sessions");
+                return;
         }
-        g_ptr_array_foreach (sessions, (GFunc)g_free, NULL);
-        g_ptr_array_free (sessions, TRUE);
+
+        call = dbus_g_proxy_begin_call (manager->priv->seat_proxy,
+                                        "GetSessions",
+                                        on_get_sessions_finished,
+                                        manager,
+                                        NULL,
+                                        G_TYPE_INVALID);
+
+        if (call == NULL) {
+                g_warning ("GdmUserManager: failed to make GetSessions call");
+                return;
+        }
+
+        manager->priv->get_sessions_call = call;
 }
 
 static void



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