summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2021-11-02 11:13:15 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-09 18:43:09 +0000
commit3ea2c1cc7b1f09da864bfebfec0b8b0624774766 (patch)
tree4c2e0aa8fd1e2d9e2e8663a36ebee1b8b86a736a
parent7f64cd03d2b8d7f8167b477e4d086c7d53db0570 (diff)
downloadqtconnectivity-3ea2c1cc7b1f09da864bfebfec0b8b0624774766.tar.gz
IOBluetooth: avoid over-retaining Obj-C entity
In the past, QBluetoothLocalDevicePrivate was releasing its instance of DarwinBTConnectionMonitor, and IOBluetoothDevice was not retaining this object, thus the correct behavior was assured. Starting from macOS 12 the behavior changed, just releasing in a dtor is not enough anymore, instead we should unregister 'monitor' manually, so that IOBluetoothDevice releases its ownership too. The problem was found when connecting to LE device which is Classic device at the same moment, resulting in IOBluetooth sending a notification to the monitor object, which has a dandling pointer to QBluetoothLocalDevicePrivate. Fixes: QTBUG-97900 Change-Id: Idcc1233ce51795c561dbee8fd6d9a7aff592a5a2 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi> (cherry picked from commit 370de7fe8447b8d2216a4cd130df211b05260b8c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/bluetooth/darwin/btconnectionmonitor.mm24
-rw-r--r--src/bluetooth/darwin/btconnectionmonitor_p.h1
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_macos.mm8
3 files changed, 24 insertions, 9 deletions
diff --git a/src/bluetooth/darwin/btconnectionmonitor.mm b/src/bluetooth/darwin/btconnectionmonitor.mm
index 7952a5f0..548fec9c 100644
--- a/src/bluetooth/darwin/btconnectionmonitor.mm
+++ b/src/bluetooth/darwin/btconnectionmonitor.mm
@@ -74,14 +74,8 @@ using namespace QT_NAMESPACE;
- (void)dealloc
{
- [discoveryNotification unregister];
- [discoveryNotification release];
-
- for (IOBluetoothUserNotification *n in foundConnections)
- [n unregister];
-
- [foundConnections release];
-
+ Q_ASSERT_X(!monitor, "-dealloc",
+ "Connection monitor was not stopped, calling -stopMonitoring is required");
[super dealloc];
}
@@ -130,4 +124,18 @@ using namespace QT_NAMESPACE;
monitor->deviceDisconnected(deviceAddress);
}
+-(void)stopMonitoring
+{
+ monitor = nullptr;
+ [discoveryNotification unregister];
+ [discoveryNotification release];
+ discoveryNotification = nil;
+
+ for (IOBluetoothUserNotification *n in foundConnections)
+ [n unregister];
+
+ [foundConnections release];
+ foundConnections = nil;
+}
+
@end
diff --git a/src/bluetooth/darwin/btconnectionmonitor_p.h b/src/bluetooth/darwin/btconnectionmonitor_p.h
index e3b7b90d..359852bc 100644
--- a/src/bluetooth/darwin/btconnectionmonitor_p.h
+++ b/src/bluetooth/darwin/btconnectionmonitor_p.h
@@ -66,6 +66,7 @@
- (void)connectionNotification:(id)notification withDevice:(IOBluetoothDevice *)device;
- (void)connectionClosedNotification:(id)notification withDevice:(IOBluetoothDevice *)device;
+- (void)stopMonitoring;
@end
#endif
diff --git a/src/bluetooth/qbluetoothlocaldevice_macos.mm b/src/bluetooth/qbluetoothlocaldevice_macos.mm
index 4d0f026d..0ee9fce7 100644
--- a/src/bluetooth/qbluetoothlocaldevice_macos.mm
+++ b/src/bluetooth/qbluetoothlocaldevice_macos.mm
@@ -68,6 +68,7 @@ public:
QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *, const QBluetoothAddress & =
QBluetoothAddress());
+ ~QBluetoothLocalDevicePrivate();
bool isValid() const;
void requestPairing(const QBluetoothAddress &address, Pairing pairing);
@@ -114,7 +115,6 @@ QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(QBluetoothLocalDevice
q_ptr(q)
{
registerQBluetoothLocalDeviceMetaType();
-
Q_ASSERT_X(q, Q_FUNC_INFO, "invalid q_ptr (null)");
QT_BT_MAC_AUTORELEASEPOOL;
@@ -153,6 +153,12 @@ QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(QBluetoothLocalDevice
DarwinBluetooth::RetainPolicy::noInitialRetain);
}
+QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
+{
+
+ [connectionMonitor stopMonitoring];
+}
+
bool QBluetoothLocalDevicePrivate::isValid() const
{
return hostController;