summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-12-14 14:34:14 +0100
committerIvan Solovev <ivan.solovev@qt.io>2023-12-15 11:46:15 +0100
commitf762e9b646e240d9e8d3d7de928ae1333227c8a0 (patch)
treec11350563df463a369cb7aa287fa275e696b46a0
parent35f853837793b6d526815140021013cf03cc80b5 (diff)
Bluetooth Windows: fix segfault in COM de-init
While doing COM initialization/deinitialization, we always implicitly assumed that QCoreApplication instance is available. However, if the Bluetooth objects are re-parented to the main application, the QCoreApplication instance will already be removed by the time we want to delete the Bluetooth object (and call COM de-init). Fix it by caching the main application's thread, and using it instead of QCoreApplication::instance()->thread() in the mainThreadCoUninit() helper method. This commit still assumes that all Bluetooth objects are created *after* the main QCoreApplication instance. Amends 340b84a5578f78d7a399e369e900ac991d9e0da2. Fixes: QTBUG-119063 Pick-to: 6.7 6.6 6.5 6.2 Change-Id: I450e4e14039ca27fcfd1f3f131789b049e1edb03 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r--src/bluetooth/qbluetoothutils_winrt.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/bluetooth/qbluetoothutils_winrt.cpp b/src/bluetooth/qbluetoothutils_winrt.cpp
index ca4326f8..b146be19 100644
--- a/src/bluetooth/qbluetoothutils_winrt.cpp
+++ b/src/bluetooth/qbluetoothutils_winrt.cpp
@@ -43,6 +43,7 @@ QByteArray byteArrayFromBuffer(const ComPtr<NativeBuffer> &buffer, bool isWCharS
}
static QSet<void*> successfulInits;
+static QThread *mainThread = nullptr;
void mainThreadCoInit(void* caller)
{
@@ -58,27 +59,33 @@ void mainThreadCoInit(void* caller)
return;
}
+ Q_ASSERT_X(!mainThread || mainThread == QThread::currentThread(),
+ __FUNCTION__, "QCoreApplication's thread has changed!");
+
// This executes in main thread which may run Gui => use apartment threaded
if (!SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
qCWarning(QT_BT_WINDOWS) << "Unexpected COM initialization result";
return;
}
successfulInits.insert(caller);
+ if (!mainThread)
+ mainThread = QThread::currentThread();
}
void mainThreadCoUninit(void* caller)
{
Q_ASSERT(caller);
- if (QThread::currentThread() != QCoreApplication::instance()->thread()) {
- qCWarning(QT_BT_WINDOWS) << "Main thread COM uninit tried from another thread";
+ if (!successfulInits.contains(caller)) {
+ qCWarning(QT_BT_WINDOWS) << "COM uninitialization without initialization";
return;
}
- if (!successfulInits.contains(caller)) {
- qCWarning(QT_BT_WINDOWS) << "COM uninitialization without initialization";
+ if (QThread::currentThread() != mainThread) {
+ qCWarning(QT_BT_WINDOWS) << "Main thread COM uninit tried from another thread";
return;
}
+
CoUninitialize();
successfulInits.remove(caller);