Skip to content

Commit d19e38a

Browse files
authored
Fix performance issue when empty_rx_queue is called before each send (#116)
1 parent 8f871ba commit d19e38a

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

isotp/protocol.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,13 +1476,17 @@ class Events:
14761476
stop_requested: threading.Event
14771477
reset_tx: threading.Event
14781478
reset_rx: threading.Event
1479+
reset_tx_complete: threading.Event
1480+
reset_rx_complete: threading.Event
14791481

14801482
def __init__(self) -> None:
14811483
self.main_thread_ready = threading.Event()
14821484
self.relay_thread_ready = threading.Event()
14831485
self.stop_requested = threading.Event()
14841486
self.reset_tx = threading.Event()
1487+
self.reset_tx_complete = threading.Event()
14851488
self.reset_rx = threading.Event()
1489+
self.reset_rx_complete = threading.Event()
14861490

14871491
started: bool
14881492
main_thread: Optional[threading.Thread]
@@ -1526,14 +1530,16 @@ def start(self) -> None:
15261530
raise RuntimeError("Transport Layer is already started")
15271531

15281532
self._set_rxfn(self._read_relay_queue)
1529-
self.main_thread = threading.Thread(target=self._main_thread_fn)
1530-
self.relay_thread = threading.Thread(target=self._relay_thread_fn)
1533+
self.main_thread = threading.Thread(target=self._main_thread_fn, daemon=True)
1534+
self.relay_thread = threading.Thread(target=self._relay_thread_fn, daemon=True)
15311535

15321536
self.events.main_thread_ready.clear()
15331537
self.events.relay_thread_ready.clear()
15341538
self.events.stop_requested.clear()
15351539
self.events.reset_tx.clear()
15361540
self.events.reset_rx.clear()
1541+
self.events.reset_tx_complete.clear()
1542+
self.events.reset_rx_complete.clear()
15371543

15381544
self.main_thread.start()
15391545
self.relay_thread.start()
@@ -1557,18 +1563,25 @@ def stop(self) -> None:
15571563
self.rx_relay_queue.put(None)
15581564

15591565
if self.main_thread is not None:
1560-
self.main_thread.join()
1566+
self.main_thread.join(1.0)
1567+
if self.main_thread.is_alive():
1568+
self.logger.error("Failed to stop the main thread")
15611569
self.main_thread = None
15621570

15631571
if self.relay_thread is not None:
1564-
self.relay_thread.join()
1572+
wait_time = max(self.default_read_timeout + 0.5, 1.0)
1573+
self.relay_thread.join(timeout=wait_time)
1574+
if self.relay_thread.is_alive():
1575+
self.logger.warning("Failed to stop the reading thread. Does your rxfn callback block without respecting the timeout parameter?")
15651576
self.relay_thread = None
15661577

15671578
self.events.main_thread_ready.clear()
15681579
self.events.relay_thread_ready.clear()
15691580
self.events.stop_requested.clear()
15701581
self.events.reset_tx.clear()
15711582
self.events.reset_rx.clear()
1583+
self.events.reset_tx_complete.clear()
1584+
self.events.reset_rx_complete.clear()
15721585

15731586
super().reset()
15741587
while not self.rx_relay_queue.empty():
@@ -1615,10 +1628,12 @@ def _main_thread_fn(self) -> None:
16151628
if self.events.reset_tx.is_set():
16161629
self._stop_sending(success=False)
16171630
self.events.reset_tx.clear()
1631+
self.events.reset_tx_complete.set()
16181632

16191633
if self.events.reset_rx.is_set():
16201634
self._stop_receiving()
16211635
self.events.reset_rx.clear()
1636+
self.events.reset_rx_complete.set()
16221637

16231638
finally:
16241639
super().reset()
@@ -1630,8 +1645,9 @@ def stop_sending(self) -> None:
16301645
if not self.events.stop_requested.is_set():
16311646
if self.main_thread is not None and self.main_thread.is_alive():
16321647
self.events.reset_tx.set()
1633-
while self.events.reset_tx.is_set():
1634-
time.sleep(0.05)
1648+
self.events.reset_tx_complete.wait(1.0)
1649+
if not self.events.reset_tx_complete.is_set():
1650+
self.logger.error("Main thread failed to stop sending when requested.")
16351651
else:
16361652
self._stop_sending(success=False)
16371653

@@ -1641,8 +1657,10 @@ def stop_receiving(self) -> None:
16411657
if not self.events.stop_requested.is_set():
16421658
if self.main_thread is not None and self.main_thread.is_alive():
16431659
self.events.reset_rx.set()
1644-
while self.events.reset_rx.is_set():
1645-
time.sleep(0.05)
1660+
self.rx_relay_queue.put(None) # Wakeup from blocking read
1661+
self.events.reset_rx_complete.wait(1.0)
1662+
if not self.events.reset_rx_complete.is_set():
1663+
self.logger.error("Main thread failed to stop receiving when requested.")
16461664
else:
16471665
self._stop_receiving()
16481666

0 commit comments

Comments
 (0)