From 680d5d25d8215a7acb1f64f718059c88bbea4b62 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Tue, 26 Feb 2019 17:23:30 +0100 Subject: [PATCH] Disconnect any leftover connections when destroying auth manager If one of these connections is triggered after destruction of auth manager, bad things happen because the slot tries to access the mutex which has gone for good along with the auth manager itself. --- src/core/auth/qgsauthmanager.cpp | 15 +++++++++++++-- src/core/auth/qgsauthmanager.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/core/auth/qgsauthmanager.cpp b/src/core/auth/qgsauthmanager.cpp index cdcb281d1729..e69b1cb5d642 100644 --- a/src/core/auth/qgsauthmanager.cpp +++ b/src/core/auth/qgsauthmanager.cpp @@ -140,12 +140,14 @@ QSqlDatabase QgsAuthManager::authDatabaseConnection() const // triggers a condition in QSqlDatabase which detects the nullptr private thread data and returns an invalid database instead. // QSqlDatabase::removeDatabase is thread safe, so this is ok to do. // Right about now is a good time to re-evaluate your selected career ;) - connect( QThread::currentThread(), &QThread::finished, QThread::currentThread(), [connectionName, this ] + QMetaObject::Connection connection = connect( QThread::currentThread(), &QThread::finished, QThread::currentThread(), [connectionName, this ] { QMutexLocker locker( mMutex ); - QgsDebugMsgLevel( QStringLiteral( "Removing outdated connection to %1 on thread exit" ).arg( connectionName ), 2 ); QSqlDatabase::removeDatabase( connectionName ); + mConnectedThreads.remove( QThread::currentThread() ); }, Qt::DirectConnection ); + + mConnectedThreads.insert( QThread::currentThread(), connection ); } } else @@ -2961,6 +2963,15 @@ void QgsAuthManager::tryToStartDbErase() QgsAuthManager::~QgsAuthManager() { + QMutexLocker locker( mMutex ); + QMapIterator iterator( mConnectedThreads ); + while ( iterator.hasNext() ) + { + iterator.next(); + iterator.key()->disconnect( iterator.value() ); + } + locker.unlock(); + if ( !isDisabled() ) { delete QgsAuthMethodRegistry::instance(); diff --git a/src/core/auth/qgsauthmanager.h b/src/core/auth/qgsauthmanager.h index a016a8de1325..e5b2fc6a869b 100644 --- a/src/core/auth/qgsauthmanager.h +++ b/src/core/auth/qgsauthmanager.h @@ -900,6 +900,8 @@ class CORE_EXPORT QgsAuthManager : public QObject //! password helper folder in the wallets static const QLatin1String AUTH_PASSWORD_HELPER_FOLDER_NAME; + mutable QMap mConnectedThreads; + friend class QgsApplication; };