chiark / gitweb /
logind: make Session.Activate() lazy
authorDavid Herrmann <dh.herrmann@gmail.com>
Tue, 17 Sep 2013 15:39:57 +0000 (17:39 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 17 Sep 2013 16:33:18 +0000 (11:33 -0500)
commitab60f2ffb1a1fe2024aea077b3f42c3653bf1df1
tree073fb209e945bb86e4aa497a2992296b4260f69e
parentae5e06bda24ebbb2ac00741738ad3a872fc577a5
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().
src/login/logind-session.c