Skip to content
Permalink
Browse files

[mssql] Fix iteration failure from background threads

We need to defer the database retrieval until iteration begins,
because otherwise we are creating the database in the main thread
and then using it in another thread (blocked in Qt 5.11, dangerous
in Qt < 5.11).
  • Loading branch information
nyalldawson committed Oct 2, 2018
1 parent b7333c0 commit dcca55c6c88abe6c43c55c975576d6e08c20458c
Showing with 26 additions and 15 deletions.
  1. +26 −15 src/providers/mssql/qgsmssqlfeatureiterator.cpp
@@ -51,21 +51,11 @@ QgsMssqlFeatureIterator::QgsMssqlFeatureIterator( QgsMssqlFeatureSource *source,

BuildStatement( request );

// connect to the database
mDatabase = QgsMssqlProvider::GetDatabase( mSource->mService, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword );

if ( !mDatabase.open() )
{
QgsDebugMsg( "Failed to open database" );
QgsDebugMsg( mDatabase.lastError().text() );
return;
}

// create sql query
mQuery.reset( new QSqlQuery( mDatabase ) );

// start selection
rewind();
// WARNING - we can't obtain the database connection now, as this method should be
// run from the main thread, yet iteration can be done in a different thread.
// This would result in failure, because QSqlDatabase instances cannot be used
// from a different thread where they were created. Instead, we defer creation
// of the database until the first feature is fetched.
}


@@ -294,6 +284,27 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature &feature )
{
feature.setValid( false );

if ( !mDatabase.isValid() )
{
// No existing connection, so set it up now. It's safe to do here as we're now in
// the thread were iteration is actually occurring.
mDatabase = QgsMssqlProvider::GetDatabase( mSource->mService, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword );

if ( !mDatabase.open() )
{
QgsDebugMsg( "Failed to open database" );
QgsDebugMsg( mDatabase.lastError().text() );
return false;
}

// create sql query
mQuery.reset( new QSqlQuery( mDatabase ) );

// start selection
if ( !rewind() )
return false;
}

if ( !mQuery )
return false;

0 comments on commit dcca55c

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