Client: Always destroy frame callback in the actual callback

It's good hygiene to destroy all frame callbacks. Destroy the
frame callback and cleanup the mFrameCallback class member in
the callback itself. The callback destruction happens before
calling handleFrameCallback() to avoid the theoretical case
where another frame callback is queued by handleFrameCallback(),
and then immediately destroyed in the callback handler.

Change-Id: Ide6dc95e3402932c58bfc088a9d471fda821e9a1
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Georges Basile Stavracas Neto 2021-05-27 20:02:53 -03:00
parent d2a37a747c
commit 0a80b46583

View File

@ -659,9 +659,13 @@ void QWaylandWindow::commit()
const wl_callback_listener QWaylandWindow::callbackListener = { const wl_callback_listener QWaylandWindow::callbackListener = {
[](void *data, wl_callback *callback, uint32_t time) { [](void *data, wl_callback *callback, uint32_t time) {
Q_UNUSED(callback);
Q_UNUSED(time); Q_UNUSED(time);
auto *window = static_cast<QWaylandWindow*>(data); auto *window = static_cast<QWaylandWindow*>(data);
Q_ASSERT(callback == window->mFrameCallback);
wl_callback_destroy(callback);
window->mFrameCallback = nullptr;
window->handleFrameCallback(); window->handleFrameCallback();
} }
}; };
@ -1366,14 +1370,6 @@ void QWaylandWindow::handleUpdate()
if (!mSurface) if (!mSurface)
return; return;
if (mFrameCallback) {
if (!isExposed())
return;
wl_callback_destroy(mFrameCallback);
mFrameCallback = nullptr;
}
QMutexLocker locker(mFrameQueue.mutex); QMutexLocker locker(mFrameQueue.mutex);
struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object())); struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mFrameQueue.queue); wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mFrameQueue.queue);