[gdm/gnome-2-30] Set up seat proxy asynchronously with users
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm/gnome-2-30] Set up seat proxy asynchronously with users
- Date: Thu, 24 Jun 2010 23:26:16 +0000 (UTC)
commit 18735c4bbf4c1e5df571f1d97283a55147a8fa47
Author: Ray Strode <rstrode redhat com>
Date: Wed Jun 23 23:05:21 2010 -0400
Set up seat proxy asynchronously with users
We don't actually need the proxy right away,
we only need it before doing other things that
use ConsoleKit so blocking other parts of
initialization for it is wrong.
This commit makes it run asynchronously with
everything else.
https://bugzilla.gnome.org/show_bug.cgi?id=622639
gui/simple-greeter/gdm-user-manager.c | 313 +++++++++++++++++++++++----------
1 files changed, 222 insertions(+), 91 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index ede66b7..d6c6ce5 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -77,12 +77,25 @@
#define RELOAD_PASSWD_THROTTLE_SECS 5
+typedef enum {
+ GDM_USER_MANAGER_SEAT_STATE_UNLOADED = 0,
+ GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID,
+ GDM_USER_MANAGER_SEAT_STATE_GET_ID,
+ GDM_USER_MANAGER_SEAT_STATE_GET_PROXY,
+ GDM_USER_MANAGER_SEAT_STATE_LOADED,
+} GdmUserManagerSeatState;
+
typedef struct
{
- char *id;
- char *session_id;
+ GdmUserManagerSeatState state;
+ char *id;
+ char *session_id;
+ union {
+ DBusGProxyCall *get_current_session_call;
+ DBusGProxyCall *get_seat_id_call;
+ };
- DBusGProxy *proxy;
+ DBusGProxy *proxy;
} GdmUserManagerSeat;
struct GdmUserManagerPrivate
@@ -138,8 +151,11 @@ static void gdm_user_manager_class_init (GdmUserManagerClass *klass);
static void gdm_user_manager_init (GdmUserManager *user_manager);
static void gdm_user_manager_finalize (GObject *object);
-static void load_users (GdmUserManager *manager);
-static void monitor_local_users (GdmUserManager *manager);
+static void load_seat_incrementally (GdmUserManager *manager);
+static void unload_seat (GdmUserManager *manager);
+static void load_users (GdmUserManager *manager);
+static void queue_load_seat_and_users (GdmUserManager *manager);
+static void monitor_local_users (GdmUserManager *manager);
static gpointer user_manager_object = NULL;
@@ -351,6 +367,7 @@ gdm_user_manager_goto_login_session (GdmUserManager *manager)
char *ssid;
g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
+ g_return_val_if_fail (manager->priv->is_loaded, FALSE);
ret = FALSE;
@@ -382,6 +399,11 @@ gdm_user_manager_can_switch (GdmUserManager *manager)
gboolean can_activate_sessions;
GError *error;
+ if (!manager->priv->is_loaded) {
+ g_debug ("GdmUserManager: Unable to switch sessions until fully loaded");
+ return FALSE;
+ }
+
if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') {
g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions");
return FALSE;
@@ -421,6 +443,7 @@ gdm_user_manager_activate_user_session (GdmUserManager *manager,
gboolean can_activate_sessions;
g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
g_return_val_if_fail (GDM_IS_USER (user), FALSE);
+ g_return_val_if_fail (manager->priv->is_loaded, FALSE);
ret = FALSE;
@@ -481,48 +504,87 @@ on_user_changed (GdmUser *user,
}
}
-static char *
-get_seat_id_for_session (DBusGConnection *connection,
- const char *session_id)
+static void
+on_get_seat_id_finished (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ GdmUserManager *manager)
{
- DBusGProxy *proxy;
- GError *error;
- char *seat_id;
- gboolean res;
+ GError *error;
+ char *seat_id;
+ gboolean res;
- proxy = NULL;
+ g_assert (manager->priv->seat.get_seat_id_call == call);
+
+ error = NULL;
seat_id = NULL;
+ res = dbus_g_proxy_end_call (proxy,
+ call,
+ &error,
+ DBUS_TYPE_G_OBJECT_PATH,
+ &seat_id,
+ G_TYPE_INVALID);
+ manager->priv->seat.get_seat_id_call = NULL;
+ g_object_unref (proxy);
- proxy = dbus_g_proxy_new_for_name (connection,
+ if (! res) {
+ if (error != NULL) {
+ g_debug ("Failed to identify the seat of the "
+ "current session: %s",
+ error->message);
+ g_error_free (error);
+ } else {
+ g_debug ("Failed to identify the seat of the "
+ "current session");
+ }
+ unload_seat (manager);
+ return;
+ }
+
+ g_debug ("GdmUserManager: Found current seat: %s", seat_id);
+
+ manager->priv->seat.id = seat_id;
+ manager->priv->seat.state++;
+
+ load_seat_incrementally (manager);
+}
+
+static void
+get_seat_id_for_current_session (GdmUserManager *manager)
+{
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
+
+ proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
CK_NAME,
- session_id,
+ manager->priv->seat.session_id,
CK_SESSION_INTERFACE);
if (proxy == NULL) {
g_warning ("Failed to connect to the ConsoleKit session object");
- goto out;
+ goto failed;
}
- error = NULL;
- res = dbus_g_proxy_call (proxy,
- "GetSeatId",
- &error,
- G_TYPE_INVALID,
- DBUS_TYPE_G_OBJECT_PATH, &seat_id,
- G_TYPE_INVALID);
- if (! res) {
- if (error != NULL) {
- g_debug ("Failed to identify the current seat: %s", error->message);
- g_error_free (error);
- } else {
- g_debug ("Failed to identify the current seat");
- }
+ call = dbus_g_proxy_begin_call (proxy,
+ "GetSeatId",
+ (DBusGProxyCallNotify)
+ on_get_seat_id_finished,
+ manager,
+ NULL,
+ G_TYPE_INVALID);
+ if (call == NULL) {
+ g_warning ("GdmUserManager: failed to make GetSeatId call");
+ goto failed;
}
- out:
+
+ manager->priv->seat.get_seat_id_call = call;
+
+ return;
+
+failed:
if (proxy != NULL) {
g_object_unref (proxy);
}
- return seat_id;
+ unload_seat (manager);
}
static char *
@@ -686,55 +748,84 @@ remove_user (GdmUserManager *manager,
}
}
-static char *
-get_current_seat_id (DBusGConnection *connection)
+static void
+on_get_current_session_finished (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ GdmUserManager *manager)
{
- DBusGProxy *proxy;
- GError *error;
- char *session_id;
- char *seat_id;
- gboolean res;
+ GError *error;
+ char *session_id;
+ gboolean res;
- proxy = NULL;
+ g_assert (manager->priv->seat.get_current_session_call == call);
+ g_assert (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID);
+
+ error = NULL;
session_id = NULL;
- seat_id = NULL;
+ res = dbus_g_proxy_end_call (proxy,
+ call,
+ &error,
+ DBUS_TYPE_G_OBJECT_PATH,
+ &session_id,
+ G_TYPE_INVALID);
+ manager->priv->seat.get_current_session_call = NULL;
+ g_object_unref (proxy);
- proxy = dbus_g_proxy_new_for_name (connection,
+ if (! res) {
+ if (error != NULL) {
+ g_debug ("Failed to identify the current session: %s",
+ error->message);
+ g_error_free (error);
+ } else {
+ g_debug ("Failed to identify the current session");
+ }
+ unload_seat (manager);
+ return;
+ }
+
+ manager->priv->seat.session_id = session_id;
+ manager->priv->seat.state++;
+
+ load_seat_incrementally (manager);
+}
+
+static void
+get_current_session_id (GdmUserManager *manager)
+{
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
+
+ proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
CK_NAME,
CK_MANAGER_PATH,
CK_MANAGER_INTERFACE);
if (proxy == NULL) {
g_warning ("Failed to connect to the ConsoleKit manager object");
- goto out;
+ goto failed;
}
- error = NULL;
- res = dbus_g_proxy_call (proxy,
- "GetCurrentSession",
- &error,
- G_TYPE_INVALID,
- DBUS_TYPE_G_OBJECT_PATH,
- &session_id,
- G_TYPE_INVALID);
- if (! res) {
- if (error != NULL) {
- g_debug ("Failed to identify the current session: %s", error->message);
- g_error_free (error);
- } else {
- g_debug ("Failed to identify the current session");
- }
- goto out;
+ call = dbus_g_proxy_begin_call (proxy,
+ "GetCurrentSession",
+ (DBusGProxyCallNotify)
+ on_get_current_session_finished,
+ manager,
+ NULL,
+ G_TYPE_INVALID);
+ if (call == NULL) {
+ g_warning ("GdmUserManager: failed to make GetCurrentSession call");
+ goto failed;
}
- seat_id = get_seat_id_for_session (connection, session_id);
+ manager->priv->seat.get_current_session_call = call;
- out:
+ return;
+
+failed:
if (proxy != NULL) {
g_object_unref (proxy);
}
- g_free (session_id);
- return seat_id;
+ unload_seat (manager);
}
static gboolean
@@ -903,13 +994,6 @@ get_seat_proxy (GdmUserManager *manager)
g_assert (manager->priv->seat.proxy == NULL);
- manager->priv->seat.id = get_current_seat_id (manager->priv->connection);
- if (manager->priv->seat.id == NULL) {
- return;
- }
-
- g_debug ("GdmUserManager: Found current seat: %s", manager->priv->seat.id);
-
error = NULL;
proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection,
CK_NAME,
@@ -925,6 +1009,7 @@ get_seat_proxy (GdmUserManager *manager)
} else {
g_warning ("Failed to connect to the ConsoleKit seat object");
}
+ unload_seat (manager);
return;
}
@@ -949,7 +1034,24 @@ get_seat_proxy (GdmUserManager *manager)
manager,
NULL);
manager->priv->seat.proxy = proxy;
+ manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED;
+}
+static void
+unload_seat (GdmUserManager *manager)
+{
+ manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
+
+ if (manager->priv->seat.proxy != NULL) {
+ g_object_unref (manager->priv->seat.proxy);
+ manager->priv->seat.proxy = NULL;
+ }
+
+ g_free (manager->priv->seat.id);
+ manager->priv->seat.id = NULL;
+
+ g_free (manager->priv->seat.session_id);
+ manager->priv->seat.session_id = NULL;
}
/**
@@ -1180,6 +1282,14 @@ maybe_set_is_loaded (GdmUserManager *manager)
return;
}
+ /* Don't set is_loaded yet unless the seat is already loaded
+ * or failed to load.
+ */
+ if (manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_LOADED
+ && manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_UNLOADED) {
+ return;
+ }
+
set_is_loaded (manager, TRUE);
}
@@ -1661,15 +1771,12 @@ load_sessions_from_array (GdmUserManager *manager,
static void
on_get_sessions_finished (DBusGProxy *proxy,
DBusGProxyCall *call,
- gpointer data)
+ GdmUserManager *manager)
{
- GdmUserManager *manager;
GError *error;
gboolean res;
GPtrArray *sessions;
- manager = GDM_USER_MANAGER (data);
-
g_assert (manager->priv->get_sessions_call == call);
error = NULL;
@@ -1716,6 +1823,7 @@ load_sessions (GdmUserManager *manager)
call = dbus_g_proxy_begin_call (manager->priv->seat.proxy,
"GetSessions",
+ (DBusGProxyCallNotify)
on_get_sessions_finished,
manager,
NULL,
@@ -1729,9 +1837,42 @@ load_sessions (GdmUserManager *manager)
manager->priv->get_sessions_call = call;
}
+static void
+load_seat_incrementally (GdmUserManager *manager)
+{
+ g_assert (manager->priv->seat.proxy == NULL);
+
+ switch (manager->priv->seat.state) {
+ case GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID:
+ get_current_session_id (manager);
+ break;
+ case GDM_USER_MANAGER_SEAT_STATE_GET_ID:
+ get_seat_id_for_current_session (manager);
+ break;
+ case GDM_USER_MANAGER_SEAT_STATE_GET_PROXY:
+ get_seat_proxy (manager);
+ break;
+ case GDM_USER_MANAGER_SEAT_STATE_LOADED:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_LOADED) {
+ gboolean res;
+
+ load_sessions (manager);
+ res = load_ck_history (manager);
+ }
+
+ maybe_set_is_loaded (manager);
+}
+
static gboolean
-load_users_idle (GdmUserManager *manager)
+load_idle (GdmUserManager *manager)
{
+ manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED + 1;
+ load_seat_incrementally (manager);
load_users (manager);
manager->priv->load_id = 0;
@@ -1739,13 +1880,13 @@ load_users_idle (GdmUserManager *manager)
}
static void
-queue_load_users (GdmUserManager *manager)
+queue_load_seat_and_users (GdmUserManager *manager)
{
if (manager->priv->load_id > 0) {
return;
}
- manager->priv->load_id = g_idle_add ((GSourceFunc)load_users_idle, manager);
+ manager->priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager);
}
static gboolean
@@ -1958,17 +2099,11 @@ monitor_local_users (GdmUserManager *manager)
static void
load_users (GdmUserManager *manager)
{
- gboolean res;
-
manager->priv->shells = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
reload_shells (manager);
-
- load_sessions (manager);
-
- res = load_ck_history (manager);
schedule_reload_passwd (manager);
}
@@ -2058,7 +2193,7 @@ gdm_user_manager_queue_load (GdmUserManager *manager)
g_return_if_fail (GDM_IS_USER_MANAGER (manager));
if (! manager->priv->is_loaded) {
- queue_load_users (manager);
+ queue_load_seat_and_users (manager);
}
}
@@ -2101,7 +2236,7 @@ gdm_user_manager_init (GdmUserManager *manager)
manager->priv->cancellable = g_cancellable_new ();
- get_seat_proxy (manager);
+ manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
}
static void
@@ -2121,6 +2256,8 @@ gdm_user_manager_finalize (GObject *object)
signal_pid (manager->priv->ck_history_pid, SIGTERM);
}
+ unload_seat (manager);
+
if (manager->priv->cancellable != NULL) {
g_object_unref (manager->priv->cancellable);
manager->priv->cancellable = NULL;
@@ -2136,10 +2273,6 @@ gdm_user_manager_finalize (GObject *object)
g_slist_free (manager->priv->include_usernames);
}
- if (manager->priv->seat.proxy != NULL) {
- g_object_unref (manager->priv->seat.proxy);
- }
-
if (manager->priv->ck_history_id != 0) {
g_source_remove (manager->priv->ck_history_id);
manager->priv->ck_history_id = 0;
@@ -2168,8 +2301,6 @@ gdm_user_manager_finalize (GObject *object)
g_file_monitor_cancel (manager->priv->shells_monitor);
g_hash_table_destroy (manager->priv->shells);
- g_free (manager->priv->seat.id);
-
G_OBJECT_CLASS (gdm_user_manager_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]