wayland: Fix internal connection teardown
The internal EventQueue is a child of the registry object. This means that after the registry is destroyed, all proxy objects in that event queue are going to have invalid reference to it, which is not a problem as long as the wl_display_dispatch() function is not called. The wl_display_dispatch() function uses wl_proxy's queue reference to enqueue incoming events to that queue. Unfortunately, during teardown, the internal ConnectionThread may dispatch events right after the registry object has been destroyed, which can lead to a crash. In order to fix the crash, we need to destroy all proxy objects and only after that we can destroy the event queue. It's okay if wayland events are dispatched in between.
This commit is contained in:
parent
7861c8d389
commit
33b2ea2058
2 changed files with 5 additions and 1 deletions
|
@ -217,6 +217,7 @@ void WaylandServer::destroyInternalConnection()
|
|||
delete m_internalConnection.compositor;
|
||||
delete m_internalConnection.seat;
|
||||
delete m_internalConnection.ddm;
|
||||
delete m_internalConnection.eventQueue; // Must be destroyed last.
|
||||
dispatch();
|
||||
m_internalConnection.client->deleteLater();
|
||||
m_internalConnection.clientThread->quit();
|
||||
|
@ -721,11 +722,12 @@ void WaylandServer::createInternalConnection()
|
|||
connect(m_internalConnection.client, &ConnectionThread::connected, this,
|
||||
[this] {
|
||||
Registry *registry = new Registry(this);
|
||||
EventQueue *eventQueue = new EventQueue(registry);
|
||||
EventQueue *eventQueue = new EventQueue(this);
|
||||
eventQueue->setup(m_internalConnection.client);
|
||||
registry->setEventQueue(eventQueue);
|
||||
registry->create(m_internalConnection.client);
|
||||
m_internalConnection.registry = registry;
|
||||
m_internalConnection.eventQueue = eventQueue;
|
||||
connect(registry, &Registry::interfacesAnnounced, this,
|
||||
[this, registry] {
|
||||
m_internalConnection.interfacesAnnounced = true;
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace KWayland
|
|||
namespace Client
|
||||
{
|
||||
class ConnectionThread;
|
||||
class EventQueue;
|
||||
class Registry;
|
||||
class Compositor;
|
||||
class Seat;
|
||||
|
@ -297,6 +298,7 @@ private:
|
|||
struct {
|
||||
KWaylandServer::ClientConnection *server = nullptr;
|
||||
KWayland::Client::ConnectionThread *client = nullptr;
|
||||
KWayland::Client::EventQueue *eventQueue = nullptr;
|
||||
QThread *clientThread = nullptr;
|
||||
KWayland::Client::Registry *registry = nullptr;
|
||||
KWayland::Client::Compositor *compositor = nullptr;
|
||||
|
|
Loading…
Reference in a new issue