From 380aaab2cc49dd0a99d81fe653dba3d9ad057a95 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 3 May 2023 13:47:15 +0300 Subject: [PATCH] Fix deleting GraphicsBuffer twice When GraphicsBuffer::dropped() is emitted, the buffer can be unreferenced. If that's the case, the GraphicsBuffer will be deleted twice: first in GraphicsBuffer::unref(), the second time in drop(). In order to address the issue, this change gets rid of the GraphicsBuffer::dropped() signal, so it's always guaranteed that the buffer stays alive until the reference count is checked. The GraphicsBuffer::dropped() signal is used to remove the mapping between wl_resource and ShmClientBuffer when the corresponding wl_shm_buffer object is destroyed. On the other hand, we could perform such cleanup when calling drop() too. This code can be further improved by reimplementing wl-shm, which we need to do at some point in the future. --- src/core/graphicsbuffer.cpp | 1 - src/core/graphicsbuffer.h | 1 - src/wayland/shmclientbuffer.cpp | 5 ++--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/core/graphicsbuffer.cpp b/src/core/graphicsbuffer.cpp index 7fc4c1d0fb..d46352e7a6 100644 --- a/src/core/graphicsbuffer.cpp +++ b/src/core/graphicsbuffer.cpp @@ -47,7 +47,6 @@ void GraphicsBuffer::unref() void GraphicsBuffer::drop() { m_dropped = true; - Q_EMIT dropped(); if (!m_refCount) { delete this; diff --git a/src/core/graphicsbuffer.h b/src/core/graphicsbuffer.h index d786c532c1..fe03e717a6 100644 --- a/src/core/graphicsbuffer.h +++ b/src/core/graphicsbuffer.h @@ -68,7 +68,6 @@ public: Q_SIGNALS: void released(); - void dropped(); protected: int m_refCount = 0; diff --git a/src/wayland/shmclientbuffer.cpp b/src/wayland/shmclientbuffer.cpp index d02e8bc27e..720d3686a4 100644 --- a/src/wayland/shmclientbuffer.cpp +++ b/src/wayland/shmclientbuffer.cpp @@ -58,6 +58,8 @@ void ShmClientBufferPrivate::buffer_destroy_callback(wl_listener *listener, void wl_shm_buffer *buffer = wl_shm_buffer_get(bufferPrivate->resource); wl_shm_pool *pool = wl_shm_buffer_ref_pool(buffer); + s_buffers.remove(bufferPrivate->resource); + wl_list_remove(&bufferPrivate->destroyListener.listener.link); wl_list_init(&bufferPrivate->destroyListener.listener.link); @@ -185,9 +187,6 @@ ShmClientBuffer *ShmClientBuffer::get(wl_resource *resource) if (wl_shm_buffer_get(resource)) { auto buffer = new ShmClientBuffer(resource); s_buffers[resource] = buffer; - connect(buffer, &ShmClientBuffer::dropped, [resource]() { - s_buffers.remove(resource); - }); return buffer; }