diff options
author | Paul Olav Tvete <paul.tvete@theqtcompany.com> | 2016-02-23 13:28:10 +0100 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@theqtcompany.com> | 2016-02-25 08:53:46 +0000 |
commit | d6fe7b6165859e17f0308cd28ab0cd2e2e3db294 (patch) | |
tree | d56f770b3eb6889859d5f3a092f89d21f8ee9e4b /src | |
parent | dd24398ce7323872413b8a21fc9ae192ff4c9f02 (diff) |
Proper fix for buffer destruction
The previous fix (93ca929fb9caf347150) would always crash on client exit.
It tried use the same destroy_listener on several buffers. Due to the
way linked lists are implemented in Wayland, a listener can only
be listening to one signal at the time.
The correct way to do this is to create a new listener for each buffer.
Change-Id: Ie94dd8cd2d3dc7f93a0526c5c585a8feab3b7354
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Reviewed-by: Louai Al-Khanji <louai.al-khanji@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index 63da3ea4a..d573edfcb 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -115,9 +115,6 @@ public: , gl_egl_image_target_texture_2d(0) , funcs(Q_NULLPTR) { - destroy_listener.d = this; - destroy_listener.listener.notify = destroy_listener_callback; - wl_list_init(&destroy_listener.listener.link); } static void destroy_listener_callback(wl_listener *listener, void *data) { @@ -127,7 +124,10 @@ public: buffer_destroy_listener *destroy_listener = reinterpret_cast<buffer_destroy_listener *>(listener); WaylandEglClientBufferIntegrationPrivate *self = destroy_listener->d; struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data); + wl_list_remove(&listener->link); + delete listener; + if (!self->buffers.contains(buffer)) return; @@ -143,11 +143,18 @@ public: self->funcs->destroy_stream(self->egl_display, state.egl_stream); } + void create_destroy_listener(struct ::wl_resource *buffer) { + buffer_destroy_listener *newListener = new buffer_destroy_listener; + newListener->d = this; + newListener->listener.notify = destroy_listener_callback; + + wl_signal_add(&buffer->destroy_signal, &newListener->listener); + } + EGLDisplay egl_display; bool valid; bool display_bound; QHash<struct ::wl_resource *, BufferState> buffers; - buffer_destroy_listener destroy_listener; PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; @@ -257,7 +264,7 @@ void WaylandEglClientBufferIntegration::initializeBuffer(struct ::wl_resource *b if (!buffer || d->buffers.contains(buffer)) return; - wl_signal_add(&buffer->destroy_signal, &d->destroy_listener.listener); + d->create_destroy_listener(buffer); } int WaylandEglClientBufferIntegration::textureTargetForBuffer(struct ::wl_resource *buffer) const |