diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-11-02 11:13:15 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-11-10 13:32:29 +0100 |
commit | bd1671ac91afafcd446e305cdb303838937eb332 (patch) | |
tree | 783668189a4ccb915afbacd26a0ebb9e12f72869 /src/bluetooth | |
parent | a7e844801e87a7e7661724c4f7525c10167c7a32 (diff) | |
download | qtconnectivity-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>
Diffstat (limited to 'src/bluetooth')
-rw-r--r-- | src/bluetooth/osx/osxbtconnectionmonitor.mm | 24 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtconnectionmonitor_p.h | 2 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_osx.mm | 6 |
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(); |