summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2017-06-01 18:06:24 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2017-06-13 18:38:36 +0000
commit63ec6a9501b86946ca5c7b9c2176b764f55a82d9 (patch)
tree69614f7b23d81b15b3942c14db7b8bf5fcabe142 /src
parent4301d682e05c678c378864cb48da489203f785e2 (diff)
Fix crash at access to unexistent controller object
Sometimes are possible a situations when triggered event callback function contains a pointer with a context of unexistent controller's object (f.e. this controller can be already deleted). That causes a crash at trying to access by this pointer. Solution is to append a pointer of each created object (or to remove a pointer of each destroyed object) to (from) some guarded vector of pointers. And then to check every received context with pointers inside of this vector. If a context does not contains in a vector, then skip any actions with this context. Change-Id: I94e237c41028724307f58bb09235299eae15d6b5 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/qlowenergycontroller_win.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/bluetooth/qlowenergycontroller_win.cpp b/src/bluetooth/qlowenergycontroller_win.cpp
index e7967dc4..89f46455 100644
--- a/src/bluetooth/qlowenergycontroller_win.cpp
+++ b/src/bluetooth/qlowenergycontroller_win.cpp
@@ -38,6 +38,7 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/QIODevice> // for open modes
#include <QtCore/QEvent>
+#include <QtCore/QMutex>
#include <algorithm> // for std::max
@@ -51,6 +52,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
Q_GLOBAL_STATIC(QLibrary, bluetoothapis)
+Q_GLOBAL_STATIC(QVector<QLowEnergyControllerPrivate *>, qControllers)
+static QMutex controllersGuard(QMutex::NonRecursive);
+
const QEvent::Type CharactericticValueEventType = static_cast<QEvent::Type>(QEvent::User + 1);
class CharactericticValueEvent : public QEvent
@@ -474,10 +478,15 @@ static void WINAPI eventChangedCallbackEntry(
if ((eventType != CharacteristicValueChangedEvent) || !eventOutParameter || !context)
return;
+ QMutexLocker locker(&controllersGuard);
+ const auto target = static_cast<QLowEnergyControllerPrivate *>(context);
+ if (!qControllers->contains(target))
+ return;
+
CharactericticValueEvent *e = new CharactericticValueEvent(
reinterpret_cast<const PBLUETOOTH_GATT_VALUE_CHANGED_EVENT>(eventOutParameter));
- QCoreApplication::postEvent(static_cast<QLowEnergyControllerPrivate *>(context), e);
+ QCoreApplication::postEvent(target, e);
}
static HANDLE registerEvent(
@@ -645,6 +654,9 @@ QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
, state(QLowEnergyController::UnconnectedState)
, error(QLowEnergyController::NoError)
{
+ QMutexLocker locker(&controllersGuard);
+ qControllers()->append(this);
+
gattFunctionsResolved = resolveFunctions(bluetoothapis());
if (!gattFunctionsResolved) {
qCWarning(QT_BT_WINDOWS) << "LE is not supported on this OS";
@@ -654,6 +666,8 @@ QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
QLowEnergyControllerPrivate::~QLowEnergyControllerPrivate()
{
+ QMutexLocker locker(&controllersGuard);
+ qControllers()->removeAll(this);
}
void QLowEnergyControllerPrivate::init()