Fix cache maybe invalid while the signal is actived from queue

with default QObject::connect signal may active from next message loop. invalide cache will hit while accessibility interface is called from windows. Invalide cache will lead to a crash

Fixes: QTBUG-106653
Change-Id: I5359672bcd60ed6cfb2edf238645225164cb1b88
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 80f44954f6872afb5aa37e6737c3e1ac68ad3577)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Jannis Xiong 2022-09-16 11:29:49 +08:00 committed by Qt Cherry-pick Bot
parent 126fe788e3
commit 6a9226b430
3 changed files with 8 additions and 1 deletions

View File

@ -74,10 +74,13 @@ QT_BEGIN_NAMESPACE
using namespace QWindowsUiAutomation; using namespace QWindowsUiAutomation;
QMutex QWindowsUiaMainProvider::m_mutex;
// Returns a cached instance of the provider for a specific accessible interface. // Returns a cached instance of the provider for a specific accessible interface.
QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible) QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible)
{ {
QMutexLocker locker(&m_mutex);
if (!accessible) if (!accessible)
return nullptr; return nullptr;
@ -275,6 +278,8 @@ ULONG QWindowsUiaMainProvider::AddRef()
ULONG STDMETHODCALLTYPE QWindowsUiaMainProvider::Release() ULONG STDMETHODCALLTYPE QWindowsUiaMainProvider::Release()
{ {
QMutexLocker locker(&m_mutex);
if (!--m_ref) { if (!--m_ref) {
delete this; delete this;
return 0; return 0;

View File

@ -47,6 +47,7 @@
#include <QtCore/qpointer.h> #include <QtCore/qpointer.h>
#include <QtCore/qsharedpointer.h> #include <QtCore/qsharedpointer.h>
#include <QtCore/qmutex.h>
#include <QtCore/qt_windows.h> #include <QtCore/qt_windows.h>
#include <QtGui/qaccessible.h> #include <QtGui/qaccessible.h>
@ -98,6 +99,7 @@ public:
private: private:
QString automationIdForAccessible(const QAccessibleInterface *accessible); QString automationIdForAccessible(const QAccessibleInterface *accessible);
ULONG m_ref; ULONG m_ref;
static QMutex m_mutex;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -75,7 +75,7 @@ void QWindowsUiaProviderCache::insert(QAccessible::Id id, QWindowsUiaBaseProvide
m_providerTable[id] = provider; m_providerTable[id] = provider;
m_inverseTable[provider] = id; m_inverseTable[provider] = id;
// Connects the destroyed signal to our slot, to remove deleted objects from the cache. // Connects the destroyed signal to our slot, to remove deleted objects from the cache.
QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::objectDestroyed); QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::objectDestroyed, Qt::DirectConnection);
} }
} }