Hi KDE developers, My name is Sheng Mao and it is my first post here. Thank you for everyone for reading this!
I have a server running Fedora 33 with KDE session through Xrdp and I connect to it with RDP from Mac (Microsoft’s RDP) and another Fedora 33 (Remmina). For the past month, I noticed a symptom: if I click “logout” in KDE and RDP session ends. But kwin_x11 keeps running in getTimestamp(), occupying 100% of a core. TL;DR: what’s the exit condition of kwin_x11 and how to make it preemptive? I have found two other similar bugs on bugs.kde.org, but it seems that they are not different issues. So I did some investigation and here is my report. 1. How Xrdp works Xrdp relies on Xrdp-sesman to launch Xvnc and start a X server. A basic process graph is as following: xrdp-sesman(68415)───xrdp-sesman(70909)─┬─Xvnc(70915)─┬─{Xvnc}(70924) │ ├─{Xvnc}(70925) │ ├─{Xvnc}(70926) │ ├─... ├─sh(70914)─┬─ssh-agent(71221) │ └─startkde(71222)───{startkde}(71234) └─xrdp-chansrv(70954)───{xrdp-chansrv}(70959) xrdp-sesman waits for end of life of at least two processes: a display (Xvnc) and a window manager (startkde). 2. How startkde works In my case, startkde is startplasma-x11.The call graph is: startplasma-x11 -> plasma_session -> kwin_x11 startplasma-x11 calls plasma_session with QProcess and it ends execution based on unregistration of two dubs services: org.kde.ksmserver and org.kde.Shutdown. plasma_session is more complicated, it runs the following eight jobs in sequence (refer to _second debug), kwin_x11 is one of them: * kcminit_startup * kded5 * kwin_x11 * ksmserver * startup phase 0 * startup phase 1 * restore session jobs * startup phase 2 3. What’s the exit condition of kwin_x11 It should be KSelectionOwner::lostOwnership. My understanding is that it is triggered by exiting of X server in this case. 4. What’s the problem When I click logout in KDE, X server ends and display is closed. This _should_ trigger KSelectionOwner::lostOwnership to end kwin_x11. However, kwin_x11 calls getTimestamp from Qt and it is a *blocking* call. The getTimestamp() works by sending dummy message to X server to get a timestamp. But now the X server is _already dead_. This blocks the *main thread* and thus KSelectionOwner::lostOwnership will never be processed. 5. How to solve that? Several ways to solve, I assume: * KDE: use a preemptive method to handle exit condition; or find a way to delay ending X server * Qt: provide a non-blocking getTimestamp() (may lead to many changes) * Xrdp-sesman: delay ending Xvnc; or use systemd slice to find active processes That’s all I find out and my thoughts. I am very new to KDE so my thoughts may be wrong. Your comments and advices are appreciated. Thank you! Sheng