wayland: Move ownership of the libinput thread to InputRedirection

When libinput tears down, it may access the Session object. This change
re-jitters the shut down logic so the Session object is guaranteed to be
valid when libinput stuff gets destroyed.

BUG: 442104
This commit is contained in:
Vlad Zahorodnii 2021-09-27 13:10:37 +03:00
parent 7900068cab
commit d7d1c6600a
4 changed files with 18 additions and 21 deletions

View file

@ -55,6 +55,7 @@
#include <KScreenLocker/KsldApp> #include <KScreenLocker/KsldApp>
// Qt // Qt
#include <QKeyEvent> #include <QKeyEvent>
#include <QThread>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
@ -2134,6 +2135,14 @@ InputRedirection::InputRedirection(QObject *parent)
InputRedirection::~InputRedirection() InputRedirection::~InputRedirection()
{ {
if (m_libInput) {
m_libInput->deleteLater();
m_libInputThread->quit();
m_libInputThread->wait();
delete m_libInputThread;
}
s_self = nullptr; s_self = nullptr;
qDeleteAll(m_filters); qDeleteAll(m_filters);
qDeleteAll(m_spies); qDeleteAll(m_spies);
@ -2374,8 +2383,15 @@ void InputRedirection::setupLibInput()
if (m_libInput) { if (m_libInput) {
return; return;
} }
m_libInputThread = new QThread();
m_libInputThread->setObjectName(QStringLiteral("libinput-connection"));
m_libInputThread->start();
LibInput::Connection *conn = LibInput::Connection::create(this); LibInput::Connection *conn = LibInput::Connection::create(this);
m_libInput = conn; m_libInput = conn;
m_libInput->moveToThread(m_libInputThread);
if (conn) { if (conn) {
if (waylandServer()) { if (waylandServer()) {

View file

@ -326,6 +326,7 @@ private:
GlobalShortcutsManager *m_shortcuts; GlobalShortcutsManager *m_shortcuts;
LibInput::Connection *m_libInput = nullptr; LibInput::Connection *m_libInput = nullptr;
QThread *m_libInputThread = nullptr;
WindowSelectorFilter *m_windowSelector = nullptr; WindowSelectorFilter *m_windowSelector = nullptr;

View file

@ -31,7 +31,6 @@
#include <QDBusPendingCall> #include <QDBusPendingCall>
#include <QMutexLocker> #include <QMutexLocker>
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QThread>
#include <libinput.h> #include <libinput.h>
#include <cmath> #include <cmath>
@ -81,7 +80,6 @@ Q_SIGNALS:
}; };
Connection *Connection::s_self = nullptr; Connection *Connection::s_self = nullptr;
QPointer<QThread> Connection::s_thread;
static ConnectionAdaptor *s_adaptor = nullptr; static ConnectionAdaptor *s_adaptor = nullptr;
static Context *s_context = nullptr; static Context *s_context = nullptr;
@ -107,16 +105,6 @@ Connection::Connection(QObject *parent)
// only here to fix build, using will crash, BUG 343529 // only here to fix build, using will crash, BUG 343529
} }
void Connection::createThread()
{
if (s_thread) {
return;
}
s_thread = new QThread();
s_thread->setObjectName(QStringLiteral("libinput-connection"));
s_thread->start();
}
Connection *Connection::create(QObject *parent) Connection *Connection::create(QObject *parent)
{ {
Q_ASSERT(!s_self); Q_ASSERT(!s_self);
@ -141,12 +129,7 @@ Connection *Connection::create(QObject *parent)
return nullptr; return nullptr;
} }
} }
Connection::createThread();
s_self = new Connection(s_context); s_self = new Connection(s_context);
s_self->moveToThread(s_thread);
QObject::connect(s_thread, &QThread::finished, s_self, &QObject::deleteLater);
QObject::connect(s_thread, &QThread::finished, s_thread, &QObject::deleteLater);
QObject::connect(parent, &QObject::destroyed, s_thread, &QThread::quit);
if (!s_adaptor) { if (!s_adaptor) {
s_adaptor = new ConnectionAdaptor(s_self); s_adaptor = new ConnectionAdaptor(s_self);
} }
@ -333,7 +316,7 @@ void Connection::processEvents()
switch (event->type()) { switch (event->type()) {
case LIBINPUT_EVENT_DEVICE_ADDED: { case LIBINPUT_EVENT_DEVICE_ADDED: {
auto device = new Device(event->nativeDevice()); auto device = new Device(event->nativeDevice());
device->moveToThread(s_thread); device->moveToThread(thread());
m_devices << device; m_devices << device;
if (device->isKeyboard()) { if (device->isKeyboard()) {
m_keyboard++; m_keyboard++;

View file

@ -87,8 +87,6 @@ public:
void updateLEDs(KWin::Xkb::LEDs leds); void updateLEDs(KWin::Xkb::LEDs leds);
static void createThread();
Q_SIGNALS: Q_SIGNALS:
void keyChanged(quint32 key, KWin::InputRedirection::KeyboardKeyState, quint32 time, KWin::LibInput::Device *device); void keyChanged(quint32 key, KWin::InputRedirection::KeyboardKeyState, quint32 time, KWin::LibInput::Device *device);
void pointerButtonChanged(quint32 button, KWin::InputRedirection::PointerButtonState state, quint32 time, KWin::LibInput::Device *device); void pointerButtonChanged(quint32 button, KWin::InputRedirection::PointerButtonState state, quint32 time, KWin::LibInput::Device *device);
@ -163,7 +161,6 @@ private:
Xkb::LEDs m_leds; Xkb::LEDs m_leds;
KWIN_SINGLETON(Connection) KWIN_SINGLETON(Connection)
static QPointer<QThread> s_thread;
}; };
} }