summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2010-06-23 22:30:02 -0400
committerRay Strode <rstrode@redhat.com>2010-06-24 18:09:08 -0400
commitf13e6afc43a8008c9d1bc86a1e64d54cc221d3b0 (patch)
tree452d219d466f2997f1e4701d399c347c466e9969
parentfe4960c1c6a9b1bf290cae7fd7b387c8fb1fbc9b (diff)
downloadgdm-f13e6afc43a8008c9d1bc86a1e64d54cc221d3b0.tar.gz
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. https://bugzilla.gnome.org/show_bug.cgi?id=622639
-rw-r--r--gui/simple-greeter/gdm-user-manager.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index f9eff90a..7138e961 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
@@ -82,6 +84,7 @@ struct GdmUserManagerPrivate
GHashTable *shells;
DBusGConnection *connection;
DBusGProxy *seat_proxy;
+ DBusGProxyCall *get_sessions_call;
char *seat_id;
GFileMonitor *passwd_monitor;
@@ -1165,6 +1168,10 @@ maybe_set_is_loaded (GdmUserManager *manager)
return;
}
+ if (manager->priv->get_sessions_call != NULL) {
+ return;
+ }
+
set_is_loaded (manager, TRUE);
}
@@ -1632,26 +1639,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",
@@ -1660,18 +1681,44 @@ load_sessions (GdmUserManager *manager)
} else {
g_warning ("unable to determine sessions for seat");
}
- return;
}
- for (i = 0; i < sessions->len; i++) {
- char *ssid;
+ manager->priv->get_sessions_call = NULL;
- ssid = g_ptr_array_index (sessions, i);
+ g_assert (sessions->len <= G_MAXINT);
+ load_sessions_from_array (manager,
+ (const char * const *) sessions->pdata,
+ (int) sessions->len);
- maybe_add_session (manager, ssid);
- }
- g_ptr_array_foreach (sessions, (GFunc)g_free, NULL);
+ g_ptr_array_foreach (sessions, (GFunc) g_free, NULL);
g_ptr_array_free (sessions, TRUE);
+
+ maybe_set_is_loaded (manager);
+}
+
+static void
+load_sessions (GdmUserManager *manager)
+{
+ DBusGProxyCall *call;
+
+ if (manager->priv->seat_proxy == NULL) {
+ g_debug ("GdmUserManager: no seat proxy; can't load sessions");
+ return;
+ }
+
+ 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 gboolean