From e961c6d9ced001acf54559e50acf0bbdab03e992 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 4 Mar 2022 20:54:28 -0600 Subject: [PATCH 1/2] Fix leak of _disconnect_futures in CentralManagerDelegate This fixes a leak of the future passed to _disconnect_futures in CentralManagerDelegate.disconnect(). As with other methods, this future is only valid for the duration of the method call. This was probably just a typo since _disconnect_callbacks also starts with _disconnect. --- CHANGELOG.rst | 4 ++++ bleak/backends/corebluetooth/CentralManagerDelegate.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 28a8bdb7..6915dad0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,8 +10,12 @@ and this project adheres to `Semantic Versioning = 5.48 Fixes #750 * Fixed unpairing does not work on windows with winrt. Fixes #699 +* Fixed leak of ``_disconnect_futures`` in ``CentralManagerDelegate``. `0.14.2`_ (2022-01-26) ====================== diff --git a/bleak/backends/corebluetooth/CentralManagerDelegate.py b/bleak/backends/corebluetooth/CentralManagerDelegate.py index 5fc3e6dd..fb0d450d 100644 --- a/bleak/backends/corebluetooth/CentralManagerDelegate.py +++ b/bleak/backends/corebluetooth/CentralManagerDelegate.py @@ -185,7 +185,7 @@ async def disconnect(self, peripheral: CBPeripheral) -> None: self.central_manager.cancelPeripheralConnection_(peripheral) await future finally: - del self._disconnect_callbacks[peripheral.identifier()] + del self._disconnect_futures[peripheral.identifier()] @objc.python_method def _changed_is_scanning(self, is_scanning: bool) -> None: From 3d2628674fbd023af019e6a8873a251e3cb7350f Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 4 Mar 2022 21:00:48 -0600 Subject: [PATCH 2/2] remove callback on disconnect in CentralManagerDelegate This removes the disconnect callback from self._disconnect_callbacks when a device disconnects. This ensures that the callback is not called more than once and that objects referenced by the callback are not leaked if the remote device initiates the disconnection and the disconnect method is never called. --- CHANGELOG.rst | 1 + bleak/backends/corebluetooth/CentralManagerDelegate.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6915dad0..b1734df6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,7 @@ Fixed * Fixed reading the battery level returns a zero-filled bytearray on linux with bluez >= 5.48 Fixes #750 * Fixed unpairing does not work on windows with winrt. Fixes #699 * Fixed leak of ``_disconnect_futures`` in ``CentralManagerDelegate``. +* Fixed callback not removed from ``_disconnect_callbacks`` on disconnect in ``CentralManagerDelegate``. `0.14.2`_ (2022-01-26) ====================== diff --git a/bleak/backends/corebluetooth/CentralManagerDelegate.py b/bleak/backends/corebluetooth/CentralManagerDelegate.py index fb0d450d..ac83c9f2 100644 --- a/bleak/backends/corebluetooth/CentralManagerDelegate.py +++ b/bleak/backends/corebluetooth/CentralManagerDelegate.py @@ -353,7 +353,8 @@ def did_disconnect_peripheral( else: future.set_result(None) - callback = self._disconnect_callbacks.get(peripheral.identifier()) + callback = self._disconnect_callbacks.pop(peripheral.identifier(), None) + if callback is not None: callback()