summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2014-06-05 17:01:48 -0400
committerRay Strode <rstrode@redhat.com>2014-06-05 17:19:33 -0400
commite24484f72bdf1d7c96131c6b7bae6409fabed210 (patch)
tree97054c10d0a1afb6cdce60300e8accc07997b4ea
parentef6954833cf43bef8306823d7fcfb6a04b903ad7 (diff)
downloadgdm-e24484f72bdf1d7c96131c6b7bae6409fabed210.tar.gz
manager: close up timed login race
Previously we would emit the timed-login-requested signal after the client connects, which might be before it was listening for the signal. Now we only emit the signal in direct response to a GetTimedLoginDetails call, which we make implicitly when the appropiate proxy interface is set up. https://bugzilla.gnome.org/show_bug.cgi?id=680348
-rw-r--r--daemon/gdm-manager.c92
-rw-r--r--daemon/gdm-session.c44
-rw-r--r--daemon/gdm-session.h2
-rw-r--r--daemon/gdm-session.xml5
-rw-r--r--libgdm/gdm-client.c24
5 files changed, 66 insertions, 101 deletions
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 9c3be71d..dbcc8bce 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1573,51 +1573,6 @@ get_display_device (GdmManager *manager,
}
static void
-on_ready_to_request_timed_login (GdmSession *session,
- GSimpleAsyncResult *result,
- gpointer *user_data)
-{
- g_debug ("GdmManager: ready to request timed login");
- int delay = GPOINTER_TO_INT (user_data);
- GCancellable *cancellable;
- char *username;
-
- cancellable = g_object_get_data (G_OBJECT (result),
- "cancellable");
- if (g_cancellable_is_cancelled (cancellable)) {
- return;
- }
-
- username = g_simple_async_result_get_source_tag (result);
-
- gdm_session_request_timed_login (session, username, delay);
-
- g_object_weak_unref (G_OBJECT (session),
- (GWeakNotify)
- g_cancellable_cancel,
- cancellable);
- g_object_weak_unref (G_OBJECT (session),
- (GWeakNotify)
- g_object_unref,
- cancellable);
- g_object_weak_unref (G_OBJECT (session),
- (GWeakNotify)
- g_free,
- username);
-
- g_free (username);
-}
-
-static gboolean
-on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
-{
- g_debug ("GdmManager: wait for greeter timeout");
- g_simple_async_result_complete (result);
-
- return FALSE;
-}
-
-static void
on_session_reauthenticated (GdmSession *session,
const char *service_name,
GdmManager *manager)
@@ -1685,53 +1640,8 @@ on_session_client_connected (GdmSession *session,
return;
}
- /* temporary hack to fix timed login
- * http://bugzilla.gnome.org/680348
- */
if (delay > 0) {
- GSimpleAsyncResult *result;
- GCancellable *cancellable;
- guint timeout_id;
- gpointer source_tag;
-
- delay = MAX (delay, 4);
-
- cancellable = g_cancellable_new ();
- source_tag = g_strdup (username);
- result = g_simple_async_result_new (G_OBJECT (session),
- (GAsyncReadyCallback)
- on_ready_to_request_timed_login,
- GINT_TO_POINTER (delay),
- source_tag);
- g_simple_async_result_set_check_cancellable (result, cancellable);
- g_object_set_data (G_OBJECT (result),
- "cancellable",
- cancellable);
-
- timeout_id = g_timeout_add_seconds_full (delay - 2,
- G_PRIORITY_DEFAULT,
- (GSourceFunc)
- on_wait_for_greeter_timeout,
- g_object_ref (result),
- (GDestroyNotify)
- g_object_unref);
- g_cancellable_connect (cancellable,
- G_CALLBACK (g_source_remove),
- GINT_TO_POINTER (timeout_id),
- NULL);
-
- g_object_weak_ref (G_OBJECT (session),
- (GWeakNotify)
- g_cancellable_cancel,
- cancellable);
- g_object_weak_ref (G_OBJECT (session),
- (GWeakNotify)
- g_object_unref,
- cancellable);
- g_object_weak_ref (G_OBJECT (session),
- (GWeakNotify)
- g_free,
- source_tag);
+ gdm_session_set_timed_login_details (session, username, delay);
}
g_free (username);
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 07eed5eb..60667c5f 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -88,6 +88,10 @@ struct _GdmSessionPrivate
char *selected_user;
char *user_x11_authority_file;
+ char *timed_login_username;
+ int timed_login_delay;
+ GList *pending_timed_login_invocations;
+
GHashTable *conversations;
GdmSessionConversation *session_conversation;
@@ -1296,6 +1300,27 @@ gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greet
}
static gboolean
+gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface,
+ GDBusMethodInvocation *invocation,
+ GdmSession *self)
+{
+
+ if (self->priv->greeter_interface != NULL) {
+ gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface,
+ invocation,
+ self->priv->timed_login_username != NULL,
+ self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
+ self->priv->timed_login_delay);
+ if (self->priv->timed_login_username != NULL) {
+ gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
+ self->priv->timed_login_username,
+ self->priv->timed_login_delay);
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *username,
@@ -1368,6 +1393,10 @@ export_greeter_interface (GdmSession *self,
"handle-start-session-when-ready",
G_CALLBACK (gdm_session_handle_client_start_session_when_ready),
self);
+ g_signal_connect (greeter_interface,
+ "handle-get-timed-login-details",
+ G_CALLBACK (gdm_session_handle_get_timed_login_details),
+ self);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (greeter_interface),
connection,
@@ -2609,16 +2638,13 @@ gdm_session_reset (GdmSession *self)
}
void
-gdm_session_request_timed_login (GdmSession *self,
- const char *username,
- int delay)
+gdm_session_set_timed_login_details (GdmSession *self,
+ const char *username,
+ int delay)
{
- g_debug ("GdmSession: requesting timed login");
- if (self->priv->greeter_interface != NULL) {
- gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
- username,
- delay);
- }
+ g_debug ("GdmSession: timed login details %s %d", username, delay);
+ self->priv->timed_login_username = g_strdup (username);
+ self->priv->timed_login_delay = delay;
}
gboolean
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index fe2eb538..8a2cb1b9 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -177,7 +177,7 @@ void gdm_session_select_session (GdmSession *session,
const char *session_name);
void gdm_session_select_user (GdmSession *session,
const char *username);
-void gdm_session_request_timed_login (GdmSession *session,
+void gdm_session_set_timed_login_details (GdmSession *session,
const char *username,
int delay);
gboolean gdm_session_client_is_connected (GdmSession *session);
diff --git a/daemon/gdm-session.xml b/daemon/gdm-session.xml
index 97216c33..2a83087b 100644
--- a/daemon/gdm-session.xml
+++ b/daemon/gdm-session.xml
@@ -85,6 +85,11 @@
<method name="BeginAutoLogin">
<arg name="username" direction="in" type="s"/>
</method>
+ <method name="GetTimedLoginDetails">
+ <arg name="enabled" direction="out" type="b"/>
+ <arg name="username" direction="out" type="s"/>
+ <arg name="delay" direction="out" type="i"/>
+ </method>
<method name="StartSessionWhenReady">
<arg name="service_name" direction="in" type="s"/>
<arg name="should_start_session" direction="in" type="b"/>
diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 4542c3ed..3cd298ee 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -794,6 +794,26 @@ gdm_client_get_user_verifier_finish (GdmClient *client,
}
static void
+on_timed_login_details_got (GdmGreeter *greeter,
+ GAsyncResult *result)
+{
+ gdm_greeter_call_get_timed_login_details_finish (greeter, NULL, NULL, NULL, result, NULL);
+}
+
+static void
+query_for_timed_login_requested_signal (GdmGreeter *greeter)
+{
+ /* This just makes sure a timed-login-requested signal gets fired
+ * off if appropriate.
+ */
+ gdm_greeter_call_get_timed_login_details (greeter,
+ NULL,
+ (GAsyncReadyCallback)
+ on_timed_login_details_got,
+ NULL);
+}
+
+static void
on_greeter_proxy_created (GObject *source,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
@@ -813,6 +833,8 @@ on_greeter_proxy_created (GObject *source,
(GDestroyNotify)
g_object_unref);
g_simple_async_result_complete_in_idle (operation_result);
+
+ query_for_timed_login_requested_signal (greeter);
}
static void
@@ -980,6 +1002,8 @@ gdm_client_get_greeter_sync (GdmClient *client,
(GWeakNotify)
g_clear_object,
&client->priv->connection);
+
+ query_for_timed_login_requested_signal (client->priv->greeter);
}
return client->priv->greeter;