Causes of session management problems in Plasma 5

Andreas Hartmetz ahartmetz at gmail.com
Tue Nov 24 01:02:46 GMT 2015


Hello,

As apparently one of the last users of session management, because I 
shut down my computers about once every day, I run into problems about 
as often as I log into a session that is supposed to be restored.
The number one problem is Konsole just not restoring.
So I took some time to investigate the problem. The result is that there 
are several bugs that conspire to break session restore. It goes about 
like this:

- ksmserver (the session manager) sends clients the "SaveYourself" 
  message and collects the responses. This works fine.
- In Qt applications, this results in a call to 
  QGuiApplicationPrivate::commitData(), which calls 
  QApplicationPrivate::tryCloseAllWindows() after the part that sends
  the SaveYourselfDone response to the session manager.
  When QGuiApplication::quitOnLastWindowClosed() is true (the default),
  this results in the application quitting.
- ksmserver notices that (e.g.) konsole has terminated and purges it
  from its internal data
- ksmserver rounds up remaining processes, which at this point do not 
  include konsole, and saves their restore data. konsole thus has saved 
  its state, but ksmserver forgot about it and doesn't remember to do
  anything with konsole when restoring the session later.

The two most obvious errors are thus:

- QGuiApplicationPrivate::commitData() calling 
  QApplicationPrivate::tryCloseAllWindows(), together with
  QGuiApplication::quitOnLastWindowClosed() being true by default. Quote 
  from documentation of signal QGuiApplication::commitDataRequest():
  "You should not exit the application within this signal. Instead, the
  session manager may or may not do this afterwards, depending on the
  context."
  Note that it says session manager and afterwards, not QGuiApplication
  and virtually immediately.

- The session manager not "locking down" or better copying the list of
  clients *while* logging out. This would arguably only help buggy
  clients, but may still be a net positive.
  Why copy the list? Logout may be canceled, so it is valuable to keep
  the main client list updated for after logout cancellation.

- Bonus: I've found that KMainWindowPrivate::init() calls 
  QCoreApplication::setQuitLockEnabled(true), which is equivalent to
  QGuiApplication::setQuitOnLastWindowClosed(true), which is either
  redundant with the default or overrides something the user has
  explicitly changed. I noticed this while trying to narrow down the 
  problem with a call to 
  QGuiApplication::setQuitOnLastWindowClosed(false) from konsole's
  Application class. Which is not a good solution, but sufficient as a
  proof of concept fix. That fix works as far as session save and 
  restore are concerned.

So now I wonder what the chances are to fix those bugs.

- Make ksmserver more robust in the face of clients dying too early,
  sure. I hope to get around to it Soon(TM).

- Remove QCoreApplication::setQuitLockEnabled(true) from 
  KMainWindowPrivate::init() - seems like a good idea to me, objections?

- Remove any window closing from QGuiApplicationPrivate::commitData() -
  this is actually an old feature that was even modified in 2014 to
  fix a problem on Windows(?!) - I guess that one is there to prevent 
  interaction after session saving, but it's a very crude way to do 
  that. IMO it would be better to do nothing, it would be even better 
  to block user input and possibly I/O handling for the duration of 
  logout and unblock them when logout is canceled.
  Note: the Windows fix is about the method being expected to *kill*
  the application, which probably comes from a lack of knowledge about X
  session management which is the main purpose of that method. Commit
  9835a63dde06a1e5d2f in qtbase.

I'd be grateful for any additional insight and / or historical 
perspective.

Cheers,
Andreas




More information about the kde-core-devel mailing list