summaryrefslogtreecommitdiff
path: root/src/login/logind-session.c
diff options
context:
space:
mode:
authorDjalal Harouni <tixxdz@opendz.org>2014-02-13 23:03:23 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-02-17 02:26:22 -0500
commit8fe63cd4f16e1e7cdf528ff053f8eb4da7848455 (patch)
tree00a5035af74da561daf7f009b34964e6a32fb297 /src/login/logind-session.c
parent9fadd4cabf57285e58272ddb75147d8d52d4c5a9 (diff)
logind: close race on session state during logins
At login there is a small race window where session_get_state() will return SESSION_ACTIVE instead of SESSION_OPENING. This must be fixed since during that time there are calls to session_save() to save session states and we want to write the correct state. When we queue the start scope and service jobs, we wait for both of them to finish before calling and continue processing in: "session_jobs_reply() => session_send_create_reply()" to create the session fifo and notify clients. However, in the match_job_removed() D-Bus signal, we may hit situations where the scope job has successfully finished and we are still waiting for the user service job to finish. During that time the "session->scope_job" will be freed and set to NULL, this makes session_get_state() return SESSION_ACTIVE before it is really active, it should return SESSION_OPENING since we are still waiting for the service job to finish in order to create the session fifo. To fix this, we also check if the session fifo fd was created, if so then the session has entered the SESSION_ACTIVE state, if not then it is still in the SESSION_OPENING state and it is waiting for the scope and service jobs to finish.
Diffstat (limited to 'src/login/logind-session.c')
-rw-r--r--src/login/logind-session.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index d4742e1134..d7c074bdce 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -915,10 +915,11 @@ void session_add_to_gc_queue(Session *s) {
SessionState session_get_state(Session *s) {
assert(s);
+ /* always check closing first */
if (s->stopping || s->timer_event_source)
return SESSION_CLOSING;
- if (s->scope_job)
+ if (s->scope_job || s->fifo_fd < 0)
return SESSION_OPENING;
if (session_is_active(s))