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.
This commit is contained in:
Vlad Zahorodnii 2023-05-03 13:47:15 +03:00
parent 4b2568bdcf
commit 380aaab2cc
3 changed files with 2 additions and 5 deletions

View file

@ -47,7 +47,6 @@ void GraphicsBuffer::unref()
void GraphicsBuffer::drop()
{
m_dropped = true;
Q_EMIT dropped();
if (!m_refCount) {
delete this;

View file

@ -68,7 +68,6 @@ public:
Q_SIGNALS:
void released();
void dropped();
protected:
int m_refCount = 0;

View file

@ -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;
}