From d1283936f739b6d6b430fec3aa1e96c38de1409a Mon Sep 17 00:00:00 2001 From: Arthur Crepin-Leblond Date: Thu, 27 Oct 2022 09:20:56 +0200 Subject: [PATCH] backends/bluezdbus/manager: Cancel the discovery on disconnect to avoid a timeout If a device disconnects while waiting for the services to be discovered, the manager will wait forever. This commit fixes that by throwing an exception in case of a disconnect. --- CHANGELOG.rst | 2 ++ bleak/backends/bluezdbus/manager.py | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3637b082..440c35be 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,8 @@ and this project adheres to `Semantic Versioning bool: except KeyError: return False + async def _wait_for_service_disovery(self, device_path: str) -> None: + """Wait for the device services to be discovered. + + If a disconnect happens before the completion a BleakError exception is raised. + + """ + services_discovered_wait_task = asyncio.create_task( + self._wait_condition(device_path, "ServicesResolved", True) + ) + device_disconnected_wait_task = asyncio.create_task( + self._wait_condition(device_path, "Connected", False) + ) + done, pending = await asyncio.wait( + {services_discovered_wait_task, device_disconnected_wait_task}, + return_when=asyncio.FIRST_COMPLETED, + ) + + for p in pending: + p.cancel() + + if device_disconnected_wait_task in done: + raise BleakError("failed to discover services, device disconnected") + async def _wait_condition( self, device_path: str, property_name: str, property_value: Any ) -> None: