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:
parent
4b2568bdcf
commit
380aaab2cc
3 changed files with 2 additions and 5 deletions
|
@ -47,7 +47,6 @@ void GraphicsBuffer::unref()
|
||||||
void GraphicsBuffer::drop()
|
void GraphicsBuffer::drop()
|
||||||
{
|
{
|
||||||
m_dropped = true;
|
m_dropped = true;
|
||||||
Q_EMIT dropped();
|
|
||||||
|
|
||||||
if (!m_refCount) {
|
if (!m_refCount) {
|
||||||
delete this;
|
delete this;
|
||||||
|
|
|
@ -68,7 +68,6 @@ public:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void released();
|
void released();
|
||||||
void dropped();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_refCount = 0;
|
int m_refCount = 0;
|
||||||
|
|
|
@ -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_buffer *buffer = wl_shm_buffer_get(bufferPrivate->resource);
|
||||||
wl_shm_pool *pool = wl_shm_buffer_ref_pool(buffer);
|
wl_shm_pool *pool = wl_shm_buffer_ref_pool(buffer);
|
||||||
|
|
||||||
|
s_buffers.remove(bufferPrivate->resource);
|
||||||
|
|
||||||
wl_list_remove(&bufferPrivate->destroyListener.listener.link);
|
wl_list_remove(&bufferPrivate->destroyListener.listener.link);
|
||||||
wl_list_init(&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)) {
|
if (wl_shm_buffer_get(resource)) {
|
||||||
auto buffer = new ShmClientBuffer(resource);
|
auto buffer = new ShmClientBuffer(resource);
|
||||||
s_buffers[resource] = buffer;
|
s_buffers[resource] = buffer;
|
||||||
connect(buffer, &ShmClientBuffer::dropped, [resource]() {
|
|
||||||
s_buffers.remove(resource);
|
|
||||||
});
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue