Skip to content

Commit dcca55c

Browse files
committed
[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).
1 parent b7333c0 commit dcca55c

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

src/providers/mssql/qgsmssqlfeatureiterator.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,11 @@ QgsMssqlFeatureIterator::QgsMssqlFeatureIterator( QgsMssqlFeatureSource *source,
5151

5252
BuildStatement( request );
5353

54-
// connect to the database
55-
mDatabase = QgsMssqlProvider::GetDatabase( mSource->mService, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword );
56-
57-
if ( !mDatabase.open() )
58-
{
59-
QgsDebugMsg( "Failed to open database" );
60-
QgsDebugMsg( mDatabase.lastError().text() );
61-
return;
62-
}
63-
64-
// create sql query
65-
mQuery.reset( new QSqlQuery( mDatabase ) );
66-
67-
// start selection
68-
rewind();
54+
// WARNING - we can't obtain the database connection now, as this method should be
55+
// run from the main thread, yet iteration can be done in a different thread.
56+
// This would result in failure, because QSqlDatabase instances cannot be used
57+
// from a different thread where they were created. Instead, we defer creation
58+
// of the database until the first feature is fetched.
6959
}
7060

7161

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

287+
if ( !mDatabase.isValid() )
288+
{
289+
// No existing connection, so set it up now. It's safe to do here as we're now in
290+
// the thread were iteration is actually occurring.
291+
mDatabase = QgsMssqlProvider::GetDatabase( mSource->mService, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword );
292+
293+
if ( !mDatabase.open() )
294+
{
295+
QgsDebugMsg( "Failed to open database" );
296+
QgsDebugMsg( mDatabase.lastError().text() );
297+
return false;
298+
}
299+
300+
// create sql query
301+
mQuery.reset( new QSqlQuery( mDatabase ) );
302+
303+
// start selection
304+
if ( !rewind() )
305+
return false;
306+
}
307+
297308
if ( !mQuery )
298309
return false;
299310

0 commit comments

Comments
 (0)