diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-11-02 11:13:15 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-09 18:43:09 +0000 |
commit | 3ea2c1cc7b1f09da864bfebfec0b8b0624774766 (patch) | |
tree | 4c2e0aa8fd1e2d9e2e8663a36ebee1b8b86a736a | |
parent | 7f64cd03d2b8d7f8167b477e4d086c7d53db0570 (diff) | |
download | qtconnectivity-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.mm | 24 | ||||
-rw-r--r-- | src/bluetooth/darwin/btconnectionmonitor_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_macos.mm | 8 |
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; |