diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2017-06-01 18:06:24 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2017-06-13 18:38:36 +0000 |
commit | 63ec6a9501b86946ca5c7b9c2176b764f55a82d9 (patch) | |
tree | 69614f7b23d81b15b3942c14db7b8bf5fcabe142 /src | |
parent | 4301d682e05c678c378864cb48da489203f785e2 (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.cpp | 16 |
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() |