Skip to content

Commit 38d4c5f

Browse files
committed
devices: wait until reader thread fully starts
On slow or highly loaded systems, the Reader thread may not be ready by the time the _send_packet method is called, resulting in a XBeeException ("Packetlistener is not running"). In order to prevent this, block in the device open() method until the reader thread is fully started. This is reproducible in the IX14 XBee prototypes when they are under heavy load (for example soon after boot). Signed-off-by: Jose Diaz de Grenu <Jose.DiazdeGrenu@digi.com>
1 parent 847fa5c commit 38d4c5f

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

digi/xbee/devices.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,7 @@ def open(self, force_settings=False):
20212021
self._packet_listener.add_micropython_data_received_callback(mp_data_cbs)
20222022

20232023
self._packet_listener.start()
2024+
self._packet_listener.wait_until_started()
20242025

20252026
if force_settings:
20262027
try:

digi/xbee/reader.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from concurrent.futures import ThreadPoolExecutor
1616
from queue import Queue, Empty
17+
from threading import Event
1718
import logging
1819
import threading
1920
import time
@@ -410,13 +411,25 @@ def __init__(self, comm_iface, xbee_device, queue_max_size=None):
410411
self.__xbee_device = xbee_device
411412
self.__comm_iface = comm_iface
412413
self.__stop = True
414+
self.__started = Event()
413415

414416
self.__queue_max_size = queue_max_size if queue_max_size is not None else self.__DEFAULT_QUEUE_MAX_SIZE
415417
self.__xbee_queue = XBeeQueue(self.__queue_max_size)
416418
self.__data_xbee_queue = XBeeQueue(self.__queue_max_size)
417419
self.__explicit_xbee_queue = XBeeQueue(self.__queue_max_size)
418420
self.__ip_xbee_queue = XBeeQueue(self.__queue_max_size)
419421

422+
def wait_until_started(self, timeout=None):
423+
"""
424+
Blocks until the thread has fully started. If already started, returns
425+
immediately.
426+
427+
Args:
428+
timeout (Float): timeout for the operation in seconds.
429+
"""
430+
431+
self.__started.wait(timeout)
432+
420433
def run(self):
421434
"""
422435
This is the method that will be executing for listening packets.
@@ -425,6 +438,7 @@ def run(self):
425438
"""
426439
try:
427440
self.__stop = False
441+
self.__started.set()
428442
while not self.__stop:
429443
# Try to read a packet. Read packet is unescaped.
430444
raw_packet = self.__comm_iface.wait_for_frame(self.__xbee_device.operating_mode)

0 commit comments

Comments
 (0)