diff options
author | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-07-28 17:53:14 +0200 |
---|---|---|
committer | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-08-03 14:05:16 +0200 |
commit | 6acc459d797b2238d7aafc10dc8f405d90b940eb (patch) | |
tree | 02cc607cd5a6fa291aff28458f48a290ad86478d | |
parent | 7038e1681863c8a59c6c6a758fc7ec41f29f2be7 (diff) | |
download | qtapplicationmanager-6acc459d797b2238d7aafc10dc8f405d90b940eb.tar.gz |
Fix potential crash when a window is released
There can be a race condition when a window is released. A crash
happens very rarely in the windowitem2 QML test case (~1%), but could
be seen more often in more complex code.
Because, both window->deleteLater() and isBeingDisplayedChanged are
processed asynchronously, the former might run before the latter and
hence the window might already be destructed when used in the
isBeingDisplayedChanged handler.
Cherry-picked from 5.15: 520d102
Change-Id: Iddb687f057666ef3d34feb6472d3ba2171093d91
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r-- | src/window-lib/windowmanager.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp index 97a3b68c..b361609a 100644 --- a/src/window-lib/windowmanager.cpp +++ b/src/window-lib/windowmanager.cpp @@ -633,10 +633,14 @@ void WindowManager::setupWindow(Window *window) emit windowPropertyChanged(win, name, value); }); - connect(window, &Window::isBeingDisplayedChanged, this, [this, window]() { - if (window->contentState() == Window::NoSurface && !window->isBeingDisplayed()) { - removeWindow(window); - releaseWindow(window); + // In very rare cases window->deleteLater() is processed before the isBeingDisplayedChanged + // handler below, i.e. the window destructor runs before the handler. + QPointer<Window> guardedWindow = window; + connect(window, &Window::isBeingDisplayedChanged, this, [this, guardedWindow]() { + if (!guardedWindow.isNull() && guardedWindow->contentState() == Window::NoSurface + && !guardedWindow->isBeingDisplayed()) { + removeWindow(guardedWindow); + releaseWindow(guardedWindow); } }, Qt::QueuedConnection); |