Skip to content

Commit

Permalink
More thread safe connection name work
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Oct 2, 2018
1 parent f4216be commit 8609052
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/providers/mssql/qgsmssqlgeomcolumntypethread.cpp
Expand Up @@ -67,7 +67,7 @@ void QgsMssqlGeomColumnTypeThread::run()
layerProperty.sql.isEmpty() ? QString() : QStringLiteral( " AND %1" ).arg( layerProperty.sql ) );

// issue the sql query
QSqlDatabase db = QSqlDatabase::database( mConnectionName );
QSqlDatabase db = QSqlDatabase::database( QgsMssqlProvider::dbConnectionName( mConnectionName ) );
if ( !QgsMssqlProvider::OpenDatabase( db ) )
{
QgsDebugMsg( db.lastError().text() );
Expand Down
22 changes: 13 additions & 9 deletions src/providers/mssql/qgsmssqlprovider.cpp
Expand Up @@ -233,19 +233,14 @@ QSqlDatabase QgsMssqlProvider::GetDatabase( const QString &service, const QStrin
else
connectionName = service;

// Starting with Qt 5.11, sharing the same connection between threads is not allowed.
// We use a dedicated connection for each thread requiring access to the database,
// using the thread address as connection name.
const QString threadAddress = QStringLiteral( ":0x%1" ).arg( reinterpret_cast< quintptr >( QThread::currentThreadId() ), 16 );
connectionName += threadAddress;

if ( !QSqlDatabase::contains( connectionName ) )
const QString threadSafeConnectionName = QgsMssqlProvider::dbConnectionName( connectionName );
if ( !QSqlDatabase::contains( threadSafeConnectionName ) )
{
db = QSqlDatabase::addDatabase( QStringLiteral( "QODBC" ), connectionName );
db = QSqlDatabase::addDatabase( QStringLiteral( "QODBC" ), threadSafeConnectionName );
db.setConnectOptions( QStringLiteral( "SQL_ATTR_CONNECTION_POOLING=SQL_CP_ONE_PER_HENV" ) );
}
else
db = QSqlDatabase::database( connectionName );
db = QSqlDatabase::database( threadSafeConnectionName );

db.setHostName( host );
QString connectionString;
Expand Down Expand Up @@ -1526,6 +1521,15 @@ QgsCoordinateReferenceSystem QgsMssqlProvider::crs() const
return mCrs;
}

QString QgsMssqlProvider::dbConnectionName( const QString &name )
{
// Starting with Qt 5.11, sharing the same connection between threads is not allowed.
// We use a dedicated connection for each thread requiring access to the database,
// using the thread address as connection name.
const QString threadAddress = QStringLiteral( ":0x%1" ).arg( reinterpret_cast< quintptr >( QThread::currentThreadId() ), 16 );
return name + threadAddress;
}

QString QgsMssqlProvider::subsetString() const
{
return mSqlWhereClause;
Expand Down
5 changes: 5 additions & 0 deletions src/providers/mssql/qgsmssqlprovider.h
Expand Up @@ -139,6 +139,11 @@ class QgsMssqlProvider : public QgsVectorDataProvider

QgsCoordinateReferenceSystem crs() const override;

/**
* Returns a thread-safe connection name for use with QSqlDatabase
*/
static QString dbConnectionName( const QString &name );

protected:
//! Loads fields from input file to member attributeFields
QVariant::Type DecodeSqlType( const QString &sqlTypeName );
Expand Down

0 comments on commit 8609052

Please sign in to comment.