diff options
author | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2020-09-11 17:42:06 +0300 |
---|---|---|
committer | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2020-10-12 19:22:03 +0300 |
commit | 45a3a3208a4243d9b0a6500e3dcd0fcfed2dfcea (patch) | |
tree | 9182afe2f97e08309b66b5b3c8c7f56d4597d5c8 | |
parent | 407c240bf52f0c5d23cd87be48ced51a58562f19 (diff) |
Scanner: Generate code that destroys inert resources
In rare cases, the compositor may need to destroy its private data
associated with a wl_resource object. For example, one such case may
arise when an output has been disconnected and the corresponding
QWaylandXdgOutputV1 object needs to be destroyed. Another case is
where some resource has become inert.
If the QWaylandXdgOutputV1 object has been destroyed and there are
still wl_resource objects associated with it, the compositor will
crash due to a segfault when somebody calls xdg_output::destroy().
With this change, qtwaylandscanner will generate code that handles
destruction of inert resources behind the scenes.
Change-Id: I0532f783ae53cc7861e0f08433dc2407aa9c7953
Reviewed-by: David Edmundson <davidedmundson@kde.org>
(cherry picked from commit 4a4c35a856cf64f0e165cc3cfaeb1a3bbbf471f6)
-rw-r--r-- | src/qtwaylandscanner/qtwaylandscanner.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index 41e8126e1..1d635f069 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -719,7 +719,10 @@ bool Scanner::process() printf(" %s::~%s()\n", interfaceName, interfaceName); printf(" {\n"); printf(" for (auto resource : qAsConst(m_resource_map))\n"); - printf(" wl_resource_set_implementation(resource->handle, nullptr, nullptr, nullptr);\n"); + printf(" resource->%s_object = nullptr;\n", interfaceNameStripped); + printf("\n"); + printf(" if (m_resource)\n"); + printf(" m_resource->%s_object = nullptr;\n", interfaceNameStripped); printf("\n"); printf(" if (m_global) {\n"); printf(" wl_global_destroy(m_global);\n"); @@ -808,10 +811,12 @@ bool Scanner::process() printf(" Resource *resource = Resource::fromResource(client_resource);\n"); printf(" Q_ASSERT(resource);\n"); printf(" %s *that = resource->%s_object;\n", interfaceName, interfaceNameStripped); - printf(" that->m_resource_map.remove(resource->client(), resource);\n"); - printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped); - printf(" if (that->m_resource == resource)\n"); - printf(" that->m_resource = nullptr;\n"); + printf(" if (Q_LIKELY(that)) {\n"); + printf(" that->m_resource_map.remove(resource->client(), resource);\n"); + printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped); + printf(" if (that->m_resource == resource)\n"); + printf(" that->m_resource = nullptr;\n"); + printf(" }\n"); printf(" delete resource;\n"); printf(" }\n"); printf("\n"); @@ -885,6 +890,11 @@ bool Scanner::process() printf(" {\n"); printf(" Q_UNUSED(client);\n"); printf(" Resource *r = Resource::fromResource(resource);\n"); + printf(" if (Q_UNLIKELY(!r->%s_object)) {\n", interfaceNameStripped); + if (e.type == "destructor") + printf(" wl_resource_destroy(resource);\n"); + printf(" return;\n"); + printf(" }\n"); printf(" static_cast<%s *>(r->%s_object)->%s_%s(\n", interfaceName, interfaceNameStripped, interfaceNameStripped, e.name.constData()); printf(" r"); for (const WaylandArgument &a : e.arguments) { |