summaryrefslogtreecommitdiff
path: root/src/login/logind-session-device.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-09-17 23:40:19 +0200
committerLennart Poettering <lennart@poettering.net>2013-09-17 17:15:30 -0500
commitd7bd01b547bd91353513131561de9cc7d9f7d405 (patch)
treecf914215fd4aae73761cc77149bfa227cc596d5d /src/login/logind-session-device.c
parent118ecf32425a590ea266b5c2b6de7962bb242356 (diff)
logind: implement generic multi-session
This enables the multi-session capability for seats that don't have VTs. For legacy seats with VTs, everything stays the same. However, all other seats now also get the multi-session capability. The only feature that was missing was session-switching. As logind can force a session-switch and signal that via the "Active" property, we only need a way to allow synchronized/delayed session switches. Compositors need to cleanup some devices before acknowledging the session switch. Therefore, we use the session-devices to give compositors a chance to block a session-switch until they cleaned everything up. If you activate a session on a seat without VTs, we send a PauseDevice signal to the active session for every active device. Only once the session acknowledged all these with a PauseDeviceComplete() call, we perform the final session switch. One important note is that delayed session-switching is meant for backwards compatibility. New compositors or other sessions should really try to deal correctly with forced session switches! They only need to handle EACCES/EPERM from syscalls and treat them as "PauseDevice" signal. Following logind patches will add a timeout to session-switches which forces the switch if the active session does not react in a timely fashion. Moreover, explicit ForceActivate() calls might also be supported. Hence, sessions must not crash if their devices get paused.
Diffstat (limited to 'src/login/logind-session-device.c')
-rw-r--r--src/login/logind-session-device.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c
index 80fd364139..e92bb54fff 100644
--- a/src/login/logind-session-device.c
+++ b/src/login/logind-session-device.c
@@ -414,10 +414,21 @@ void session_device_free(SessionDevice *sd) {
}
void session_device_complete_pause(SessionDevice *sd) {
+ SessionDevice *iter;
+ Iterator i;
+
if (!sd->active)
return;
session_device_stop(sd);
+
+ /* if not all devices are paused, wait for further completion events */
+ HASHMAP_FOREACH(iter, sd->session->devices, i)
+ if (iter->active)
+ return;
+
+ /* complete any pending session switch */
+ seat_complete_switch(sd->session->seat);
}
void session_device_resume_all(Session *s) {
@@ -449,3 +460,20 @@ void session_device_pause_all(Session *s) {
}
}
}
+
+unsigned int session_device_try_pause_all(Session *s) {
+ SessionDevice *sd;
+ Iterator i;
+ unsigned int num_pending = 0;
+
+ assert(s);
+
+ HASHMAP_FOREACH(sd, s->devices, i) {
+ if (sd->active) {
+ session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
+ ++num_pending;
+ }
+ }
+
+ return num_pending;
+}