|
3 | 3 | """
|
4 | 4 |
|
5 | 5 | import asyncio
|
| 6 | +import functools |
6 | 7 | import logging
|
7 | 8 | import threading
|
8 | 9 | import time
|
9 |
| -from typing import Awaitable, Callable, Iterable, List, Optional, Union |
| 10 | +from typing import Awaitable, Callable, Iterable, List, Optional, Union, cast |
10 | 11 |
|
11 | 12 | from can.bus import BusABC
|
12 | 13 | from can.listener import Listener
|
@@ -108,28 +109,33 @@ def stop(self, timeout: float = 5) -> None:
|
108 | 109 | listener.stop()
|
109 | 110 |
|
110 | 111 | def _rx_thread(self, bus: BusABC) -> None:
|
111 |
| - try: |
112 |
| - while self._running: |
| 112 | + # determine message handling callable early, not inside while loop |
| 113 | + handle_message = cast( |
| 114 | + Callable[[Message], None], |
| 115 | + self._on_message_received |
| 116 | + if self._loop is None |
| 117 | + else functools.partial( |
| 118 | + self._loop.call_soon_threadsafe, self._on_message_received |
| 119 | + ), |
| 120 | + ) |
| 121 | + |
| 122 | + while self._running: |
| 123 | + try: |
113 | 124 | if msg := bus.recv(self.timeout):
|
114 | 125 | with self._lock:
|
115 |
| - if self._loop is not None: |
116 |
| - self._loop.call_soon_threadsafe( |
117 |
| - self._on_message_received, msg |
118 |
| - ) |
119 |
| - else: |
120 |
| - self._on_message_received(msg) |
121 |
| - except Exception as exc: # pylint: disable=broad-except |
122 |
| - self.exception = exc |
123 |
| - if self._loop is not None: |
124 |
| - self._loop.call_soon_threadsafe(self._on_error, exc) |
125 |
| - # Raise anyway |
126 |
| - raise |
127 |
| - elif not self._on_error(exc): |
128 |
| - # If it was not handled, raise the exception here |
129 |
| - raise |
130 |
| - else: |
131 |
| - # It was handled, so only log it |
132 |
| - logger.info("suppressed exception: %s", exc) |
| 126 | + handle_message(msg) |
| 127 | + except Exception as exc: # pylint: disable=broad-except |
| 128 | + self.exception = exc |
| 129 | + if self._loop is not None: |
| 130 | + self._loop.call_soon_threadsafe(self._on_error, exc) |
| 131 | + # Raise anyway |
| 132 | + raise |
| 133 | + elif not self._on_error(exc): |
| 134 | + # If it was not handled, raise the exception here |
| 135 | + raise |
| 136 | + else: |
| 137 | + # It was handled, so only log it |
| 138 | + logger.debug("suppressed exception: %s", exc) |
133 | 139 |
|
134 | 140 | def _on_message_available(self, bus: BusABC) -> None:
|
135 | 141 | if msg := bus.recv(0):
|
|
0 commit comments