Skip to content
Permalink
Browse files
QgisApp::closeProject(): cancel canvas jobs before closing the projec…
…t, to avoid rendering jobs to access deleted objects (fixes #44144)
  • Loading branch information
rouault authored and nyalldawson committed Nov 1, 2021
1 parent 9a04cd8 commit 8df016d402ddec8ca3d972e0802623a16bff540f
Showing with 27 additions and 10 deletions.
  1. +1 −0 python/gui/auto_generated/qgsmapcanvas.sip.in
  2. +1 −0 src/app/qgisapp.cpp
  3. +19 −10 src/gui/qgsmapcanvas.cpp
  4. +6 −0 src/gui/qgsmapcanvas.h
@@ -133,6 +133,7 @@ Make sure to remove any rendered images from cache (does nothing if cache is not
.. versionadded:: 2.4
%End


void waitWhileRendering();
%Docstring
Blocks until the rendering job has finished.
@@ -13387,6 +13387,7 @@ void QgisApp::closeProject()
// clear out any stuff from project
mMapCanvas->setLayers( QList<QgsMapLayer *>() );
mMapCanvas->clearCache();
mMapCanvas->cancelJobs();
mOverviewCanvas->setLayers( QList<QgsMapLayer *>() );

// Avoid unnecessary layer changed handling for each layer removed - instead,
@@ -242,12 +242,30 @@ QgsMapCanvas::~QgsMapCanvas()
}
mLastNonZoomMapTool = nullptr;

cancelJobs();

// delete canvas items prior to deleting the canvas
// because they might try to update canvas when it's
// already being destructed, ends with segfault
qDeleteAll( mScene->items() );

mScene->deleteLater(); // crashes in python tests on windows

delete mCache;
delete mLabelingResults;
}


void QgsMapCanvas::cancelJobs()
{

// rendering job may still end up writing into canvas map item
// so kill it before deleting canvas items
if ( mJob )
{
whileBlocking( mJob )->cancel();
delete mJob;
mJob = nullptr;
}

QList< QgsMapRendererQImageJob * >::const_iterator previewJob = mPreviewJobs.constBegin();
@@ -259,18 +277,9 @@ QgsMapCanvas::~QgsMapCanvas()
delete *previewJob;
}
}

// delete canvas items prior to deleting the canvas
// because they might try to update canvas when it's
// already being destructed, ends with segfault
qDeleteAll( mScene->items() );

mScene->deleteLater(); // crashes in python tests on windows

delete mCache;
delete mLabelingResults;
}


void QgsMapCanvas::setMagnificationFactor( double factor, const QgsPointXY *center )
{
// do not go higher or lower than min max magnification ratio
@@ -183,6 +183,12 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView, public QgsExpressionContex
*/
void clearCache();

/**
* Cancel any rendering job, in a blocking way. Used for application closing.
* \note not available in Python bindings
*/
void cancelJobs() SIP_SKIP;

/**
* Blocks until the rendering job has finished.
*

0 comments on commit 8df016d

Please sign in to comment.