summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-09-17 17:39:57 +0200
committerLennart Poettering <lennart@poettering.net>2013-09-17 11:33:18 -0500
commitab60f2ffb1a1fe2024aea077b3f42c3653bf1df1 (patch)
tree073fb209e945bb86e4aa497a2992296b4260f69e
parentae5e06bda24ebbb2ac00741738ad3a872fc577a5 (diff)
logind: make Session.Activate() lazy
Currently, Activate() calls chvt(), which does an ioctl(VT_ACTIVATE) and immediately calls seat_set_active(). However, VTs are allowed to prevent being deactivated. Therefore, logind cannot be sure the VT_ACTIVATE call was actually successful. Furthermore, compositors often need to clean up their devices before they acknowledge the VT switch. The immediate call to seat_set_active() may modify underlying ACLs, though. Thus, some compositors may fail cleaning up their stuff. Moreover, the compositor being switched to (if listening to logind instead of VTs) will not be able to activate its devices if the old VT still has them active. We could simply add an VT_WAITACTIVE call, which blocks until the given VT is active. However, this can block forever if the compositor hangs. So to fix this, we make Activate() lazy. That is, it only schedules a session-switch but does not wait for it to complete. The caller can no longer rely on it being immediate. Instead, a caller is required to wait for the PropertiesChanged signal and read the "Active" field. We could make Activate() wait asynchronously for the session-switch to complete and then send the return-message afterwards. However, this would add a lot of state-tracking with no real gain: 1) Sessions normally don't care whether Activate() was actually successful as they currently _must_ wait for the VT activation to do anything for real. 2) Error messages for failed session switches can be printed by logind instead of the session issuing Activate(). 3) Sessions that require synchronous Activate() calls can simply issue the call and then wait for "Active" properties to change. This also allows them to implement their own timeout. This change prepares for multi-session on seats without VTs. Forced VT switches are always bad as compositors cannot perform any cleanup. This isn't strictly required, but may lead to loss of information and ambiguous error messages. So for multi-session on seats without VTs, we must wait for the current session to clean-up before finalizing the session-switch. This requires Activate() to be lazy as we cannot block here. Note that we can always implement a timeout which allows us to guarantee the session switch to happen. Nevertheless, this calls for a lazy Activate().
-rw-r--r--src/login/logind-session.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index fe5fa27be1..fa8b5157e8 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -360,8 +360,6 @@ int session_load(Session *s) {
}
int session_activate(Session *s) {
- int r;
-
assert(s);
assert(s->user);
@@ -376,11 +374,7 @@ int session_activate(Session *s) {
assert(seat_is_vtconsole(s->seat));
- r = chvt(s->vtnr);
- if (r < 0)
- return r;
-
- return seat_set_active(s->seat, s);
+ return chvt(s->vtnr);
}
static int session_link_x11_socket(Session *s) {