[gdm/multi-stack: 8/35] Store multiple conversations in the session



commit d3004477cb4424526f6ae2132d0554501cd9ffc5
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jan 16 15:18:31 2009 -0500

    Store multiple conversations in the session
    
    We keep multiple conversations in the session now, keyed off of
    PAM service is at the other end.  Much of the guts still
    only operate on the first conversation added though.

 daemon/gdm-session-direct.c |  132 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 106 insertions(+), 26 deletions(-)
---
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 86bd59d..9af8252 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -84,6 +84,7 @@ struct _GdmSessionDirectPrivate
         char                *user_x11_authority_file;
 
         GdmSessionConversation *conversation;
+        GHashTable          *conversations;
 
         guint32              is_authenticated : 1;
         guint32              is_running : 1;
@@ -1450,6 +1451,42 @@ allow_user_function (DBusConnection *connection,
         return FALSE;
 }
 
+static GdmSessionConversation *
+find_conversation_by_name (GdmSessionDirect *session,
+                           const char       *service_name)
+{
+        GdmSessionConversation *conversation;
+
+        conversation = g_hash_table_lookup (session->priv->conversations, service_name);
+
+        if (conversation == NULL) {
+                g_warning ("Tried to look up non-existant conversation");
+        }
+
+        return conversation;
+}
+
+static GdmSessionConversation *
+find_conversation_by_pid (GdmSessionDirect *session,
+                          GPid              pid)
+{
+        GHashTableIter iter;
+        gpointer key, value;
+
+        g_hash_table_iter_init (&iter, session->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                if (conversation->worker_pid == pid) {
+                        return conversation;
+                }
+        }
+
+        return NULL;
+}
+
 static void
 handle_connection (DBusServer      *server,
                    DBusConnection  *new_connection,
@@ -1457,10 +1494,22 @@ handle_connection (DBusServer      *server,
 {
         GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
         GdmSessionConversation *conversation;
+        gulong pid;
 
         g_debug ("GdmSessionDirect: Handing new connection");
 
-        conversation = session->priv->conversation;
+        if (!dbus_connection_get_unix_process_id (new_connection, &pid)) {
+                g_warning ("Unable to read pid on new worker connection");
+                return;
+        }
+
+        conversation = find_conversation_by_pid (session, (GPid) pid);
+
+        if (conversation == NULL) {
+                g_warning ("New worker connection is from unknown source");
+                return;
+        }
+
         if (conversation->worker_connection == NULL) {
                 DBusObjectPathVTable vtable = { &session_unregister_handler,
                                                 &session_message_handler,
@@ -1533,6 +1582,17 @@ setup_server (GdmSessionDirect *session)
 }
 
 static void
+free_conversation (GdmSessionConversation *conversation)
+{
+        if (conversation->job != NULL) {
+                g_warning ("Freeing conversation with active job");
+        }
+
+        g_free (conversation->service_name);
+        g_free (conversation);
+}
+
+static void
 gdm_session_direct_init (GdmSessionDirect *session)
 {
         session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session,
@@ -1556,6 +1616,11 @@ gdm_session_direct_init (GdmSessionDirect *session)
                           G_CALLBACK (on_session_exited),
                           NULL);
 
+        session->priv->conversations = g_hash_table_new_full (g_str_hash,
+                                                              g_str_equal,
+                                                              (GDestroyNotify) g_free,
+                                                              (GDestroyNotify)
+                                                              free_conversation);
         session->priv->environment = g_hash_table_new_full (g_str_hash,
                                                             g_str_equal,
                                                             (GDestroyNotify) g_free,
@@ -1659,8 +1724,6 @@ stop_conversation (GdmSessionConversation *conversation)
                                               G_CALLBACK (worker_died),
                                               conversation);
 
-        cancel_pending_query (session);
-
         if (conversation->worker_connection != NULL) {
                 dbus_connection_remove_filter (conversation->worker_connection, on_message, session);
 
@@ -1669,9 +1732,9 @@ stop_conversation (GdmSessionConversation *conversation)
         }
 
         gdm_session_worker_job_stop (conversation->job);
+
         g_object_unref (conversation->job);
-        g_free (conversation->service_name);
-        g_free (conversation);
+        conversation->job = NULL;
 }
 
 static void
@@ -1679,12 +1742,20 @@ gdm_session_direct_start_conversation (GdmSession *session,
                                        const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
+        GdmSessionConversation *conversation;
 
         g_return_if_fail (session != NULL);
 
         g_debug ("GdmSessionDirect: starting conversation");
 
-        impl->priv->conversation = start_conversation (impl, service_name);
+        conversation = start_conversation (impl, service_name);
+
+        g_hash_table_insert (impl->priv->conversations,
+                             g_strdup (service_name), conversation);
+
+        if (impl->priv->conversation != NULL) {
+                impl->priv->conversation = conversation;
+        }
 }
 
 static void
@@ -1735,8 +1806,8 @@ send_setup (GdmSessionDirect *session,
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
 
-        conversation = session->priv->conversation;
-        if (! send_dbus_message (conversation, message)) {
+        conversation = find_conversation_by_name (session, service_name);
+        if (conversation != NULL && ! send_dbus_message (conversation, message)) {
                 g_debug ("GdmSessionDirect: Could not send %s signal", "Setup");
         }
 
@@ -1798,8 +1869,8 @@ send_setup_for_user (GdmSessionDirect *session,
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
 
-        conversation = session->priv->conversation;
-        if (! send_dbus_message (conversation, message)) {
+        conversation = find_conversation_by_name (session, service_name);
+        if (conversation != NULL && ! send_dbus_message (conversation, message)) {
                 g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForUser");
         }
 
@@ -1813,8 +1884,6 @@ gdm_session_direct_setup (GdmSession *session,
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
 
         g_return_if_fail (session != NULL);
-        g_return_if_fail (impl->priv->conversation != NULL);
-        g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
 
         send_setup (impl, service_name);
         gdm_session_direct_defaults_changed (impl);
@@ -1828,8 +1897,6 @@ gdm_session_direct_setup_for_user (GdmSession *session,
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
 
         g_return_if_fail (session != NULL);
-        g_return_if_fail (impl->priv->conversation != NULL);
-        g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
         g_return_if_fail (username != NULL);
 
         gdm_session_direct_select_user (session, username);
@@ -2061,6 +2128,28 @@ gdm_session_direct_start_session (GdmSession *session)
 }
 
 static void
+stop_all_conversations (GdmSessionDirect *session)
+{
+        GHashTableIter iter;
+        gpointer key, value;
+
+        if (session->priv->conversations == NULL) {
+                return;
+        }
+
+        g_hash_table_iter_init (&iter, session->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                stop_conversation (conversation);
+        }
+
+        g_hash_table_remove_all (session->priv->conversations);
+}
+
+static void
 gdm_session_direct_close (GdmSession *session)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
@@ -2077,6 +2166,8 @@ gdm_session_direct_close (GdmSession *session)
                                            impl->priv->display_device);
         }
 
+        stop_all_conversations (impl);
+
         g_free (impl->priv->selected_user);
         impl->priv->selected_user = NULL;
 
@@ -2121,20 +2212,9 @@ gdm_session_direct_answer_query  (GdmSession *session,
 static void
 gdm_session_direct_cancel  (GdmSession *session)
 {
-        GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
-        GHashTableIter iter;
-        gpointer key, value;
-
         g_return_if_fail (session != NULL);
 
-        g_hash_table_iter_init (&iter, impl->priv->conversations);
-        while (g_hash_table_iter_next (&iter, &key, &value)) {
-                GdmSessionConversation *conversation;
-
-                conversation = (GdmSessionConversation *) value;
-
-                cancel_pending_query (conversation);
-        }
+        stop_all_conversations (GDM_SESSION_DIRECT (session));
 }
 
 char *



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