QWaylandWindow::handleUpdate could create thousands of pending frame callbacks, causing compositor to terminate client connection. https://bugreports.qt.io/browse/QTBUG-81504 * gnu/packages/patches/qtwayland-dont-recreate-callbacks.patch: New file. * gnu/packages/patches/qtwayland-cleanup-callbacks.patch: New file. * gnu/local.mk (dist_patch_DATA): Adjust accordingly. * gnu/packages/qt.scm (qtwayland)[source](patches): Add patches.
		
			
				
	
	
		
			52 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 42cdc61a93cf2acb09936aebb5e431fdbc0a26c6 Mon Sep 17 00:00:00 2001
 | |
| From: Georges Basile Stavracas Neto <gbsneto@gnome.org>
 | |
| Date: Thu, 27 May 2021 20:02:53 -0300
 | |
| Subject: [PATCH] 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>
 | |
| ---
 | |
|  src/client/qwaylandwindow.cpp | 14 +++++---------
 | |
|  1 file changed, 5 insertions(+), 9 deletions(-)
 | |
| 
 | |
| diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
 | |
| index d83d51695..5561f58f7 100644
 | |
| --- a/src/client/qwaylandwindow.cpp
 | |
| +++ b/src/client/qwaylandwindow.cpp
 | |
| @@ -659,9 +659,13 @@ void QWaylandWindow::commit()
 | |
|  
 | |
|  const wl_callback_listener QWaylandWindow::callbackListener = {
 | |
|      [](void *data, wl_callback *callback, uint32_t time) {
 | |
| -        Q_UNUSED(callback);
 | |
|          Q_UNUSED(time);
 | |
|          auto *window = static_cast<QWaylandWindow*>(data);
 | |
| +
 | |
| +        Q_ASSERT(callback == window->mFrameCallback);
 | |
| +        wl_callback_destroy(callback);
 | |
| +        window->mFrameCallback = nullptr;
 | |
| +
 | |
|          window->handleFrameCallback();
 | |
|      }
 | |
|  };
 | |
| @@ -1366,11 +1370,6 @@ void QWaylandWindow::handleUpdate()
 | |
|      if (!mSurface)
 | |
|          return;
 | |
|  
 | |
| -    if (mFrameCallback) {
 | |
| -        wl_callback_destroy(mFrameCallback);
 | |
| -        mFrameCallback = nullptr;
 | |
| -    }
 | |
| -
 | |
|      QMutexLocker locker(mFrameQueue.mutex);
 | |
|      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);
 | |
| -- 
 | |
| 2.38.1
 | |
| 
 |