Skip to content

Commit e8aa3aa

Browse files
authored
Modifications in 'bus.py' to avoid reader thread exceptions.
For a detailed description see: Design issue: Using "notifier" inside "with can.Bus(…) as bus" statement has no sufficient clean-up for reader threats. #1526 #1526
1 parent 751dd13 commit e8aa3aa

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

can/bus.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class BusABC(metaclass=ABCMeta):
4444
#: Log level for received messages
4545
RECV_LOGGING_LEVEL = 9
4646

47+
#: Keep track about occupaition by a notifier
48+
_notifier: Any = None
49+
4750
@abstractmethod
4851
def __init__(
4952
self,
@@ -410,6 +413,37 @@ def _matches_filters(self, msg: Message) -> bool:
410413
# nothing matched
411414
return False
412415

416+
@property
417+
def notifier(self):
418+
"""
419+
Return the current notifier
420+
"""
421+
return self._notifier
422+
423+
def set_notifier(self, new_notifier, replace:bool=False) -> None:
424+
"""
425+
Set the new notifier
426+
427+
:raises ~can.exceptions.CanOperationError:
428+
If the bus still occupied by an other notifier and replace flag is False.
429+
"""
430+
if self._notifier == None:
431+
self._notifier = new_notifier
432+
else:
433+
if replace == False:
434+
raise CanOperationError("Bus still occupied by a notifier.")
435+
else:
436+
self.release_from_notifier()
437+
self._notifier = new_notifier
438+
439+
def release_from_notifier(self):
440+
"""
441+
Remove this bus from current notifier and release occupation
442+
"""
443+
if self._notifier != None:
444+
# Mypy prefers this over a hasattr(...) check
445+
getattr(self._notifier, "remove_bus", lambda: None)(self)
446+
413447
def flush_tx_buffer(self) -> None:
414448
"""Discard every message that may be queued in the output buffer(s)."""
415449

@@ -419,6 +453,7 @@ def shutdown(self) -> None:
419453
in shutting down a bus.
420454
"""
421455
self.stop_all_periodic_tasks()
456+
self.release_from_notifier()
422457

423458
def __enter__(self):
424459
return self

0 commit comments

Comments
 (0)