Commit 2093820a authored by Vlad Zahorodnii's avatar Vlad Zahorodnii

xwayland: Avoid creating a tree query on crash

If Xwayland has crashed, the Workspace will block stacking order updates
and start destroying all X11 clients.

Once stacking order updates are unblocked, the Workspace will mark the X
stacking order as dirty and create a new Xcb::Tree object.

We don't want to create that Xcb::Tree object because accessing it
after the XCB connection has been shut down will lead to a crash.

BUG: 427688
FIXED-IN: 5.20.1
parent 37ffba8b
......@@ -5,8 +5,10 @@
*/
#include "kwin_wayland_test.h"
#include "composite.h"
#include "main.h"
#include "platform.h"
#include "scene.h"
#include "screens.h"
#include "unmanaged.h"
#include "wayland_server.h"
......@@ -124,6 +126,11 @@ void XwaylandServerCrashTest::testCrash()
QCOMPARE(kwinApp()->x11DefaultScreen(), nullptr);
QCOMPARE(kwinApp()->x11RootWindow(), XCB_WINDOW_NONE);
QCOMPARE(kwinApp()->x11ScreenNumber(), -1);
// Render a frame to ensure that the compositor doesn't crash.
Compositor::self()->addRepaintFull();
QSignalSpy frameRenderedSpy(Compositor::self()->scene(), &Scene::frameRendered);
QVERIFY(frameRenderedSpy.wait());
}
} // namespace KWin
......
......@@ -5,8 +5,10 @@
*/
#include "kwin_wayland_test.h"
#include "composite.h"
#include "main.h"
#include "platform.h"
#include "scene.h"
#include "screens.h"
#include "wayland_server.h"
#include "workspace.h"
......@@ -103,6 +105,11 @@ void XwaylandServerRestartTest::testRestart()
QCOMPARE(client->windowId(), window);
QVERIFY(client->isDecorated());
// Render a frame to ensure that the compositor doesn't crash.
Compositor::self()->addRepaintFull();
QSignalSpy frameRenderedSpy(Compositor::self()->scene(), &Scene::frameRendered);
QVERIFY(frameRenderedSpy.wait());
// Destroy the test window.
xcb_destroy_window(c.data(), window);
xcb_flush(c.data());
......
......@@ -159,6 +159,13 @@ public:
return m_defaultScreen;
}
/**
* Returns @c true if we're in the middle of destroying the X11 connection.
*/
bool isClosingX11Connection() const {
return m_isClosingX11Connection;
}
#ifdef KWIN_BUILD_ACTIVITIES
bool usesKActivities() const {
return m_useKActivities;
......@@ -234,6 +241,9 @@ protected:
void setTerminating() {
m_terminating = true;
}
void setClosingX11Connection(bool set) {
m_isClosingX11Connection = set;
}
protected:
static int crashes;
......@@ -253,6 +263,7 @@ private:
#endif
Platform *m_platform = nullptr;
bool m_terminating = false;
bool m_isClosingX11Connection = false;
};
inline static Application *kwinApp()
......
......@@ -1788,7 +1788,7 @@ bool Workspace::compositing() const
void Workspace::markXStackingOrderAsDirty()
{
m_xStackingDirty = true;
if (kwinApp()->x11Connection()) {
if (kwinApp()->x11Connection() && !kwinApp()->isClosingX11Connection()) {
m_xStackingQueryTree.reset(new Xcb::Tree(kwinApp()->x11RootWindow()));
}
}
......
......@@ -149,6 +149,8 @@ void Xwayland::stop()
return;
}
m_app->setClosingX11Connection(true);
// If Xwayland has crashed, we must deactivate the socket notifier and ensure that no X11
// events will be dispatched before blocking; otherwise we will simply hang...
uninstallSocketNotifier();
......@@ -169,6 +171,8 @@ void Xwayland::stop()
m_xwaylandProcess = nullptr;
waylandServer()->destroyXWaylandConnection(); // This one must be destroyed last!
m_app->setClosingX11Connection(false);
}
void Xwayland::restart()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment