Add an assert to protect multiple calls to QgsSymbolV2::startRender()

while rendering has already been started for a particular symbol instance

Relates to a random but frequent crash which occurs when using the
categorised symbol renderer - tracked down to a race condition
in which multiple concurrent calls to startRender() are performed
on a single symbol instance.
This commit is contained in:
Nyall Dawson 2017-07-10 11:29:00 +10:00
parent 67c6e8f2b8
commit fabf32efc5
2 changed files with 10 additions and 0 deletions

View File

@ -383,6 +383,9 @@ bool QgsSymbol::changeSymbolLayer( int index, QgsSymbolLayer *layer )
void QgsSymbol::startRender( QgsRenderContext &context, const QgsFields &fields )
{
Q_ASSERT_X( !mStarted, "startRender", "Rendering has already been started for this symbol instance!" );
mStarted = true;
mSymbolRenderContext.reset( new QgsSymbolRenderContext( context, outputUnit(), mOpacity, false, mRenderHints, nullptr, fields, mapUnitScale() ) );
QgsSymbolRenderContext symbolContext( context, outputUnit(), mOpacity, false, mRenderHints, nullptr, fields, mapUnitScale() );
@ -402,6 +405,9 @@ void QgsSymbol::startRender( QgsRenderContext &context, const QgsFields &fields
void QgsSymbol::stopRender( QgsRenderContext &context )
{
Q_ASSERT_X( mStarted, "startRender", "startRender was not called for this symbol instance!" );
mStarted = false;
Q_UNUSED( context )
if ( mSymbolRenderContext )
{

View File

@ -388,6 +388,10 @@ class CORE_EXPORT QgsSymbol
QgsSymbol( const QgsSymbol & );
#endif
//! True if render has already been started - guards against multiple calls to
//! startRender() (usually a result of not cloning a shared symbol instance before rendering).
bool mStarted = false;
//! Initialized in startRender, destroyed in stopRender
std::unique_ptr< QgsSymbolRenderContext > mSymbolRenderContext;