summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-12-20 15:03:36 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-01-17 11:19:16 +0000
commit1c5c34385ac10f42283197eaa798a502f6c34f1f (patch)
treea661db0a19d589aa73d3cf66a826ea8ff09723a7
parent2ee2bf5f26216a6bd67f239a5aa6193367f9933e (diff)
QWinRTLowEnergyServiceHandler: optimize behavior at disconnect
The QWinRTLowEnergyServiceHandler helper class is used to query low energy service details. It works in a background thread and performs multiple async operations to get the results. As the class works in a background thread, we use QWinRTFunctions::await() to wait for the results of async operations. This allows to simplify the code. In practice the user might want to disconnect from the device while service details discovery is performed. Previously the background thread was still performing all the requests. This patch handles the already-existing QLowEnergyControllerPrivateWinRT::abortConnection() signal and provides the exit condition to all QWinRTFunctions::await() calls, so that the background thread does not do unnecessary work. Task-number: QTBUG-108461 Change-Id: I1db05c906beb0078de8a00fd5e32d589306f6665 Reviewed-by: Juha Vuolle <juha.vuolle@qt.io> (cherry picked from commit c68e5d0952036204b8d20b26f0de362b36c03511) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 3cebc697..8c61b4ee 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -131,6 +131,8 @@ public:
public slots:
void obtainCharList()
{
+ auto exitCondition = [this]() { return mAbortRequested; };
+
mIndicateChars.clear();
qCDebug(QT_BT_WINDOWS) << __FUNCTION__;
ComPtr<IAsyncOperation<GattCharacteristicsResult *>> characteristicsOp;
@@ -138,7 +140,8 @@ public slots:
HRESULT hr = mDeviceService->GetCharacteristicsAsync(&characteristicsOp);
EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr);
hr = QWinRTFunctions::await(characteristicsOp, characteristicsResult.GetAddressOf(),
- QWinRTFunctions::ProcessMainThreadEvents, 5000);
+ QWinRTFunctions::ProcessMainThreadEvents, 5000,
+ exitCondition);
EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr);
GattCommunicationStatus status;
hr = characteristicsResult->get_Status(&status);
@@ -156,7 +159,7 @@ public slots:
EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr);
mCharacteristicsCountToBeDiscovered = characteristicsCount;
- for (uint i = 0; i < characteristicsCount; ++i) {
+ for (uint i = 0; !mAbortRequested && (i < characteristicsCount); ++i) {
ComPtr<IGattCharacteristic> characteristic;
hr = characteristics->GetAt(i, &characteristic);
if (FAILED(hr)) {
@@ -182,7 +185,9 @@ public slots:
DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain list of descriptors")
ComPtr<IGattDescriptorsResult> descResult;
- hr = QWinRTFunctions::await(descAsyncOp, descResult.GetAddressOf());
+ hr = QWinRTFunctions::await(descAsyncOp, descResult.GetAddressOf(),
+ QWinRTFunctions::ProcessMainThreadEvents, 5000,
+ exitCondition);
DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain descriptor read result")
quint16 handle;
@@ -211,7 +216,9 @@ public slots:
&readOp);
DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not read characteristic")
ComPtr<IGattReadResult> readResult;
- hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(),
+ QWinRTFunctions::ProcessMainThreadEvents, 5000,
+ exitCondition);
DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr,
"Could not obtain characteristic read result")
if (!readResult)
@@ -237,7 +244,7 @@ public slots:
uint descriptorCount;
hr = descriptors->get_Size(&descriptorCount);
DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain list of descriptors' size")
- for (uint j = 0; j < descriptorCount; ++j) {
+ for (uint j = 0; !mAbortRequested && (j < descriptorCount); ++j) {
QLowEnergyServicePrivate::DescData descData;
ComPtr<IGattDescriptor> descriptor;
hr = descriptors->GetAt(j, &descriptor);
@@ -257,7 +264,9 @@ public slots:
&readOp);
WARN_AND_CONTINUE_IF_FAILED(hr, "Could not read descriptor value")
ComPtr<IClientCharConfigDescriptorResult> readResult;
- hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(),
+ QWinRTFunctions::ProcessMainThreadEvents, 5000,
+ exitCondition);
WARN_AND_CONTINUE_IF_FAILED(hr, "Could not await descriptor read result")
GattClientCharacteristicConfigurationDescriptorValue value;
hr = readResult->get_ClientCharacteristicConfigurationDescriptor(&value);
@@ -289,8 +298,10 @@ public slots:
&readOp);
WARN_AND_CONTINUE_IF_FAILED(hr, "Could not read descriptor value")
ComPtr<IGattReadResult> readResult;
- hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
- WARN_AND_CONTINUE_IF_FAILED(hr, "Could await descriptor read result")
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(),
+ QWinRTFunctions::ProcessMainThreadEvents, 5000,
+ exitCondition);
+ WARN_AND_CONTINUE_IF_FAILED(hr, "Could not await descriptor read result")
if (descData.uuid == QBluetoothUuid::DescriptorType::CharacteristicUserDescription)
descData.value = byteArrayFromGattResult(readResult, true);
else
@@ -306,6 +317,11 @@ public slots:
checkAllCharacteristicsDiscovered();
}
+ void setAbortRequested()
+ {
+ mAbortRequested = true;
+ }
+
private:
bool checkAllCharacteristicsDiscovered();
void emitErrorAndQuitThread(HRESULT hr);
@@ -320,6 +336,7 @@ public:
quint16 mStartHandle = 0;
quint16 mEndHandle = 0;
QList<QBluetoothUuid> mIndicateChars;
+ bool mAbortRequested = false;
signals:
void charListObtained(const QBluetoothUuid &service,
@@ -336,6 +353,8 @@ bool QWinRTLowEnergyServiceHandler::checkAllCharacteristicsDiscovered()
mStartHandle, mEndHandle);
QThread::currentThread()->quit();
return true;
+ } else if (mAbortRequested) {
+ QThread::currentThread()->quit();
}
return false;
@@ -1281,6 +1300,8 @@ void QLowEnergyControllerPrivateWinRT::discoverServiceDetailsHelper(
connect(thread, &QThread::started, worker, &QWinRTLowEnergyServiceHandler::obtainCharList);
connect(thread, &QThread::finished, worker, &QObject::deleteLater);
connect(worker, &QObject::destroyed, thread, &QObject::deleteLater);
+ connect(this, &QLowEnergyControllerPrivateWinRT::abortConnection,
+ worker, &QWinRTLowEnergyServiceHandler::setAbortRequested);
connect(worker, &QWinRTLowEnergyServiceHandler::errorOccured,
this, &QLowEnergyControllerPrivateWinRT::handleServiceHandlerError);
connect(worker, &QWinRTLowEnergyServiceHandler::charListObtained, this,