summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2021-11-02 11:13:15 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2021-11-10 13:32:29 +0100
commitbd1671ac91afafcd446e305cdb303838937eb332 (patch)
tree783668189a4ccb915afbacd26a0ebb9e12f72869
parenta7e844801e87a7e7661724c4f7525c10167c7a32 (diff)
downloadqtconnectivity-bd1671ac91afafcd446e305cdb303838937eb332.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: Timur Pocheptsov <timur.pocheptsov@qt.io>
-rw-r--r--src/bluetooth/osx/osxbtconnectionmonitor.mm24
-rw-r--r--src/bluetooth/osx/osxbtconnectionmonitor_p.h2
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_osx.mm6
3 files changed, 24 insertions, 8 deletions
diff --git a/src/bluetooth/osx/osxbtconnectionmonitor.mm b/src/bluetooth/osx/osxbtconnectionmonitor.mm
index 3f041be7..bc955c75 100644
--- a/src/bluetooth/osx/osxbtconnectionmonitor.mm
+++ b/src/bluetooth/osx/osxbtconnectionmonitor.mm
@@ -81,14 +81,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];
}
@@ -137,4 +131,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/osx/osxbtconnectionmonitor_p.h b/src/bluetooth/osx/osxbtconnectionmonitor_p.h
index 3442ee09..0b19b4e4 100644
--- a/src/bluetooth/osx/osxbtconnectionmonitor_p.h
+++ b/src/bluetooth/osx/osxbtconnectionmonitor_p.h
@@ -84,6 +84,8 @@ QT_END_NAMESPACE
- (void)connectionNotification:(id)notification withDevice:(IOBluetoothDevice *)device;
- (void)connectionClosedNotification:(id)notification withDevice:(IOBluetoothDevice *)device;
+- (void)stopMonitoring;
+
@end
#endif
diff --git a/src/bluetooth/qbluetoothlocaldevice_osx.mm b/src/bluetooth/qbluetoothlocaldevice_osx.mm
index 82986356..72655690 100644
--- a/src/bluetooth/qbluetoothlocaldevice_osx.mm
+++ b/src/bluetooth/qbluetoothlocaldevice_osx.mm
@@ -66,6 +66,7 @@ public:
QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *, const QBluetoothAddress & =
QBluetoothAddress());
+ ~QBluetoothLocalDevicePrivate();
bool isValid() const;
void requestPairing(const QBluetoothAddress &address, Pairing pairing);
@@ -147,6 +148,11 @@ QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(QBluetoothLocalDevice
connectionMonitor.reset([[ObjCConnectionMonitor alloc] initWithMonitor:this]);
}
+QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
+{
+ [connectionMonitor stopMonitoring];
+}
+
bool QBluetoothLocalDevicePrivate::isValid() const
{
return hostController.data();