diff options
author | Djalal Harouni <tixxdz@opendz.org> | 2014-02-13 23:03:23 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2014-02-17 02:26:22 -0500 |
commit | 8fe63cd4f16e1e7cdf528ff053f8eb4da7848455 (patch) | |
tree | 00a5035af74da561daf7f009b34964e6a32fb297 /src | |
parent | 9fadd4cabf57285e58272ddb75147d8d52d4c5a9 (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')
-rw-r--r-- | src/login/logind-session.c | 3 |
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)) |