Skip to content

Commit

Permalink
[wayland] Fix a crash when an application exits. JB#44844
Browse files Browse the repository at this point in the history
Two things try to delete QWaylandSurfaceInterface instances, the
QWaylandSurface they were created for and the wayland resource they
represent. In my case the QWaylandSurface is doing so first and there
was a subsequent crash due to an access after deletion by the code
generated resource destroy callback which can be avoided by destroying
the resource from within the object destructor and shortcutting the
consquent destruction. The reverse order will still be a problem.
  • Loading branch information
adenexter committed Jun 28, 2019
1 parent e068950 commit 3894881
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
14 changes: 12 additions & 2 deletions src/compositor/wayland_wrapper/qwlextendedsurface.cpp
Expand Up @@ -65,6 +65,7 @@ ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int vers
, QtWaylandServer::qt_extended_surface(client, id, version)
, m_surface(surface)
, m_windowFlags(0)
, m_destroyed(false)
{
Q_ASSERT(surface->extendedSurface() == 0);
surface->setExtendedSurface(this);
Expand All @@ -74,6 +75,12 @@ ExtendedSurface::~ExtendedSurface()
{
if (m_surface)
m_surface->setExtendedSurface(0);

if (!m_destroyed) {
m_destroyed = true;

wl_resource_destroy(resource()->handle);
}
}

void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant)
Expand Down Expand Up @@ -179,9 +186,12 @@ void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int3
emit m_surface->waylandSurface()->windowFlagsChanged(windowFlags);
}

void ExtendedSurface::extended_surface_destroy_resource(Resource *)
void ExtendedSurface::extended_surface_destroy_resource(Resource *resource)
{
delete this;
if (!m_destroyed) {
m_destroyed = true;
delete this;
}
}

void ExtendedSurface::extended_surface_raise(Resource *)
Expand Down
2 changes: 2 additions & 0 deletions src/compositor/wayland_wrapper/qwlextendedsurface_p.h
Expand Up @@ -121,6 +121,8 @@ class ExtendedSurface : public QWaylandSurfaceInterface, public QtWaylandServer:
QByteArray m_authenticationToken;
QVariantMap m_windowProperties;

bool m_destroyed;

void extended_surface_update_generic_property(Resource *resource,
const QString &name,
struct wl_array *value) Q_DECL_OVERRIDE;
Expand Down
16 changes: 13 additions & 3 deletions src/compositor/wayland_wrapper/qwlshellsurface.cpp
Expand Up @@ -98,6 +98,7 @@ ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface
, m_moveGrabber(0)
, m_popupGrabber(0)
, m_popupSerial()
, m_destroyed(false)
{
m_view = surface->compositor()->waylandCompositor()->createView(surface->waylandSurface());
connect(surface->waylandSurface(), &QWaylandSurface::configure, this, &ShellSurface::configure);
Expand All @@ -106,6 +107,11 @@ ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface

ShellSurface::~ShellSurface()
{
if (!m_destroyed) {
m_destroyed = true;

wl_resource_destroy(resource()->handle);
}
}

void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height)
Expand Down Expand Up @@ -192,10 +198,14 @@ void ShellSurface::requestSize(const QSize &size)

void ShellSurface::shell_surface_destroy_resource(Resource *)
{
if (m_popupGrabber)
m_popupGrabber->removePopup(this);
if (!m_destroyed) {
m_destroyed = true;

if (m_popupGrabber)
m_popupGrabber->removePopup(this);

delete this;
delete this;
}
}

void ShellSurface::shell_surface_move(Resource *resource,
Expand Down
2 changes: 2 additions & 0 deletions src/compositor/wayland_wrapper/qwlshellsurface_p.h
Expand Up @@ -132,6 +132,8 @@ private Q_SLOTS:

QSet<uint32_t> m_pings;

bool m_destroyed;

void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;

void shell_surface_move(Resource *resource,
Expand Down

0 comments on commit 3894881

Please sign in to comment.