summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-11-25 18:22:14 +0100
committerIvan Solovev <ivan.solovev@qt.io>2021-11-26 09:30:17 +0100
commit978dbaa9e975968dd6bacf36f70238c9b61643b4 (patch)
tree26143ccb4c5eea96f1b52735256c215e37d6932a
parent1e76f0f9af3db8cb7299d0f8cf9df7876cbb3e0a (diff)
downloadqtconnectivity-978dbaa9e975968dd6bacf36f70238c9b61643b4.tar.gz
Windows: fix object destruction order when terminating helper threads
Windows implementation of QLowEnergyController is using helper threads to perform device connection and characteristics read for services. In both cases a new QObject-derived class instance is created and moved to a helper QThread. A QThread::finished signal was used to destroy both the helper thread and the object. This was creating a situation when the order of destruction for a thread and a nested object was not specified. In practice that could lead to hangs when reading multiple service characteristics, which is specially seen on Windows 11. This patch uses QThread::finished signal to destroy only the nested object. Later on, the object's QObject::destroyed signal is used to destroy the thread itself. Task-number: QTBUG-97578 Change-Id: Ic973b835496b6098d47cd1e124315903c143e3e1 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> (cherry picked from commit 981e3f10f48580641f5e2365953ec8a17b5c96a2)
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp2
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new.cpp4
2 files changed, 3 insertions, 3 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 9109102e..6d8898e9 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -642,8 +642,8 @@ void QLowEnergyControllerPrivateWinRT::discoverServiceDetails(const QBluetoothUu
QThread *thread = new QThread;
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &QWinRTLowEnergyServiceHandler::obtainCharList);
- connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(thread, &QThread::finished, worker, &QObject::deleteLater);
+ connect(worker, &QObject::destroyed, thread, &QObject::deleteLater);
connect(worker, &QWinRTLowEnergyServiceHandler::charListObtained, this,
[this](const QBluetoothUuid &service, QHash<QLowEnergyHandle, QLowEnergyServicePrivate::CharData> charList
, QVector<QBluetoothUuid> indicateChars
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new.cpp b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
index 5f8d5de5..e90073a4 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_new.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
@@ -711,8 +711,8 @@ void QLowEnergyControllerPrivateWinRTNew::connectToDevice()
connect(this, &QLowEnergyControllerPrivateWinRTNew::abortConnection, worker,
&QWinRTLowEnergyConnectionHandler::handleDeviceDisconnectRequest);
connect(thread, &QThread::started, worker, &QWinRTLowEnergyConnectionHandler::connectToDevice);
- connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(thread, &QThread::finished, worker, &QObject::deleteLater);
+ connect(worker, &QObject::destroyed, thread, &QObject::deleteLater);
connect(worker, &QWinRTLowEnergyConnectionHandler::errorOccurred, this,
[this](const QString &msg) { handleConnectionError(msg.toUtf8().constData()); });
connect(worker, &QWinRTLowEnergyConnectionHandler::deviceConnected, this,
@@ -1166,8 +1166,8 @@ void QLowEnergyControllerPrivateWinRTNew::discoverServiceDetails(const QBluetoot
QThread *thread = new QThread;
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &QWinRTLowEnergyServiceHandlerNew::obtainCharList);
- connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(thread, &QThread::finished, worker, &QObject::deleteLater);
+ connect(worker, &QObject::destroyed, thread, &QObject::deleteLater);
connect(worker, &QWinRTLowEnergyServiceHandlerNew::errorOccured,
this, &QLowEnergyControllerPrivateWinRTNew::handleServiceHandlerError);
connect(worker, &QWinRTLowEnergyServiceHandlerNew::charListObtained, this,