summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Zahorodnii <vlad.zahorodnii@kde.org>2020-09-11 17:42:06 +0300
committerVlad Zahorodnii <vlad.zahorodnii@kde.org>2020-10-12 19:22:03 +0300
commit45a3a3208a4243d9b0a6500e3dcd0fcfed2dfcea (patch)
tree9182afe2f97e08309b66b5b3c8c7f56d4597d5c8
parent407c240bf52f0c5d23cd87be48ced51a58562f19 (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.cpp20
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) {