Skip to content

Commit

Permalink
bluezdbus/client: Make sure the disconnect monitor task is properly c…
Browse files Browse the repository at this point in the history
…ancelled.

Sometimes the exception on connect is raised so early that the
disconnect monitor task does not get the disconnect event set because the
on_connected_changed callback is already unregistered and the task stays
in pending state causing asyncio to throw an exception:
"Task was destroyed but it is pending!"
  • Loading branch information
arthur-proglove committed Dec 1, 2022
1 parent 22610ae commit 1ccc8c0
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Added
* Added optional hack to use Bluetooth address instead of UUID on macOS.
* Added ``BleakScanner.find_device_by_name()`` class method.
* Added optional command line argument to use debug log level to all applicable examples.
* Make sure the disconnect monitor task is properly cancelled on the BlueZ client.

Changed
-------
Expand Down
9 changes: 7 additions & 2 deletions bleak/backends/bluezdbus/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ def on_value_changed(char_path: str, value: bytes) -> None:
)
self._remove_device_watcher = lambda: manager.remove_device_watcher(watcher)

local_disconnect_monitor_event = asyncio.Event()

try:
try:
#
Expand Down Expand Up @@ -197,10 +199,10 @@ def on_value_changed(char_path: str, value: bytes) -> None:
self._is_connected = True

# Create a task that runs until the device is disconnected.
self._disconnect_monitor_event = asyncio.Event()
self._disconnect_monitor_event = local_disconnect_monitor_event
asyncio.ensure_future(
self._disconnect_monitor(
self._bus, self._device_path, self._disconnect_monitor_event
self._bus, self._device_path, local_disconnect_monitor_event
)
)

Expand Down Expand Up @@ -246,6 +248,9 @@ def on_value_changed(char_path: str, value: bytes) -> None:

raise
except BaseException:
# this effectively cancels the disconnect monitor in case the event
# was not triggered by a D-Bus callback
local_disconnect_monitor_event.set()
self._cleanup_all()
raise

Expand Down

0 comments on commit 1ccc8c0

Please sign in to comment.