Skip to content
Permalink
Browse files

Fix crash when loading WCS layers (fixes #15595)

The problem is that some providers would still issue network
requests in prepareJobs() - this should be ideally avoided,
because it is run in main thread - all the work should be deferred
to be done in worker thread.
  • Loading branch information
wonder-sk committed Oct 5, 2016
1 parent ed8c02f commit 08f4a0f40cce21d5730653a75bdd44f175f3b0b8
@@ -98,14 +98,6 @@ void QgsMapRendererCustomPainterJob::start()
}

mLayerJobs = prepareJobs( mPainter, mLabelingEngine, mLabelingEngineV2 );
// prepareJobs calls mapLayer->createMapRenderer may involve cloning a RasterDataProvider,
// whose constructor may need to download some data (i.e. WMS, AMS) and doing so runs a
// QEventLoop waiting for the network request to complete. If unluckily someone calls
// mapCanvas->refresh() while this is happening, QgsMapRendererCustomPainterJob::cancel is
// called, deleting the QgsMapRendererCustomPainterJob while this function is running.
// Hence we need to check whether the job is still active before proceeding
if ( !isActive() )
return;

QgsDebugMsg( "Rendering prepared in (seconds): " + QString( "%1" ).arg( prepareTime.elapsed() / 1000.0 ) );

@@ -76,14 +76,6 @@ void QgsMapRendererParallelJob::start()
}

mLayerJobs = prepareJobs( nullptr, mLabelingEngine, mLabelingEngineV2 );
// prepareJobs calls mapLayer->createMapRenderer may involve cloning a RasterDataProvider,
// whose constructor may need to download some data (i.e. WMS, AMS) and doing so runs a
// QEventLoop waiting for the network request to complete. If unluckily someone calls
// mapCanvas->refresh() while this is happening, QgsMapRendererCustomPainterJob::cancel is
// called, deleting the QgsMapRendererCustomPainterJob while this function is running.
// Hence we need to check whether the job is still active before proceeding
if ( !isActive() )
return;

QgsDebugMsg( QString( "QThreadPool max thread count is %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );

@@ -706,9 +706,6 @@ void QgsMapCanvas::refreshMap()

stopRendering(); // if any...

// from now on we can accept refresh requests again
mRefreshScheduled = false;

//build the expression context
QgsExpressionContext expressionContext;
expressionContext << QgsExpressionContextUtils::globalScope()
@@ -741,6 +738,14 @@ void QgsMapCanvas::refreshMap()

mJob->start();

// from now on we can accept refresh requests again
// this must be reset only after the job has been started, because
// some providers (yes, it's you WCS and AMS!) during preparation
// do network requests and start an internal event loop, which may
// end up calling refresh() and would schedule another refresh,
// deleting the one we have just started.
mRefreshScheduled = false;

mMapUpdateTimer.start();

emit renderStarting();

0 comments on commit 08f4a0f

Please sign in to comment.
You can’t perform that action at this time.