Skip to content

Commit 049288a

Browse files
committed
mavproxy.py: Clean up log_writer exit
* Use threading.Event instead of daemon thread to avoid uncaught exception on ctrl+C exit * Daemon threads are not recommended anymore Signed-off-by: Ryan Friedman <25047695+Ryanf55@users.noreply.github.com>
1 parent 5127953 commit 049288a

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

MAVProxy/mavproxy.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ def __init__(self):
8787
self.mav_error = 0
8888
self.altitude = 0
8989
self.last_distance_announce = 0.0
90-
self.exit = False
90+
# A newer thread event to stop MAVProxy
91+
self.stop_event = threading.Event()
9192
self.flightmode = 'MAV'
9293
self.last_mode_announce = 0
9394
self.last_mode_announced = 'MAV'
@@ -807,7 +808,7 @@ def process_stdin(line):
807808
print("%-15s : %s" % (cmd, help))
808809
return
809810
if cmd == 'exit' and mpstate.settings.requireexit:
810-
mpstate.status.exit = True
811+
mpstate.status.stop_event.set()
811812
return
812813

813814
if cmd not in command_map:
@@ -936,8 +937,12 @@ def mkdir_p(dir):
936937

937938
def log_writer():
938939
'''log writing thread'''
939-
while not mpstate.status.exit:
940-
mpstate.logfile_raw.write(bytearray(mpstate.logqueue_raw.get()))
940+
while not mpstate.status.stop_event.is_set():
941+
if not mpstate.logqueue_raw.empty():
942+
bytes = mpstate.logqueue_raw.get(block=False)
943+
mpstate.logfile_raw.write(bytearray(bytes))
944+
945+
# TODO consider wait() the stop event instead
941946
timeout = time.time() + 10
942947
while not mpstate.logqueue_raw.empty() and time.time() < timeout:
943948
mpstate.logfile_raw.write(mpstate.logqueue_raw.get())
@@ -948,6 +953,7 @@ def log_writer():
948953
mpstate.logfile_raw.flush()
949954

950955

956+
951957
# If state_basedir is NOT set then paths for logs and aircraft
952958
# directories are relative to mavproxy's cwd
953959
def log_paths():
@@ -1009,18 +1015,17 @@ def open_telemetry_logs(logpath_telem, logpath_telem_raw):
10091015
stat = os.statvfs(logpath_telem)
10101016
if stat.f_bfree*stat.f_bsize < 209715200:
10111017
print("ERROR: Not enough free disk space for logfile")
1012-
mpstate.status.exit = True
1018+
mpstate.status.stop_event.set()
10131019
return
10141020

10151021
# use a separate thread for writing to the logfile to prevent
10161022
# delays during disk writes (important as delays can be long if camera
10171023
# app is running)
10181024
t = threading.Thread(target=log_writer, name='log_writer')
1019-
t.daemon = True
10201025
t.start()
10211026
except Exception as e:
10221027
print("ERROR: opening log file for writing: %s" % e)
1023-
mpstate.status.exit = True
1028+
mpstate.status.stop_event.set()
10241029
return
10251030

10261031

@@ -1121,7 +1126,7 @@ def main_loop():
11211126
set_stream_rates()
11221127

11231128
while True:
1124-
if mpstate is None or mpstate.status.exit:
1129+
if mpstate is None or mpstate.status.stop_event.is_set():
11251130
return
11261131

11271132
# enable or disable screensaver:
@@ -1218,12 +1223,12 @@ def main_loop():
12181223

12191224
def input_loop():
12201225
'''wait for user input'''
1221-
while mpstate.status.exit is not True:
1226+
while not mpstate.status.stop_event.is_set():
12221227
try:
12231228
line = mpstate.rl.input()
12241229
mpstate.input_queue.put(line)
12251230
except (EOFError, IOError):
1226-
mpstate.status.exit = True
1231+
not mpstate.status.stop_event.set()
12271232

12281233

12291234
def run_script(scriptfile):
@@ -1407,7 +1412,6 @@ def run_startup_scripts():
14071412

14081413
# global mavproxy state
14091414
mpstate = MPState()
1410-
mpstate.status.exit = False
14111415
mpstate.command_map = command_map
14121416
mpstate.continue_mode = opts.continue_mode
14131417
# queues for logging
@@ -1447,11 +1451,11 @@ def run_startup_scripts():
14471451

14481452
def quit_handler(signum=None, frame=None):
14491453
# print('Signal handler called with signal', signum)
1450-
if mpstate.status.exit:
1454+
if mpstate.status.stop_event.is_set():
14511455
print('Clean shutdown impossible, forcing an exit')
14521456
sys.exit(0)
14531457
else:
1454-
mpstate.status.exit = True
1458+
mpstate.status.stop_event.set()
14551459

14561460
# Listen for kill signals to cleanly shutdown modules
14571461
fatalsignals = [signal.SIGTERM]
@@ -1584,7 +1588,7 @@ def quit_handler(signum=None, frame=None):
15841588

15851589
# use main program for input. This ensures the terminal cleans
15861590
# up on exit
1587-
while (mpstate.status.exit is not True):
1591+
while not mpstate.status.stop_event.is_set():
15881592
try:
15891593
if opts.daemon or opts.non_interactive:
15901594
time.sleep(0.1)
@@ -1606,7 +1610,7 @@ def quit_handler(signum=None, frame=None):
16061610
m.init(mpstate)
16071611

16081612
else:
1609-
mpstate.status.exit = True
1613+
mpstate.status.stop_event.set()
16101614
sys.exit(1)
16111615

16121616
if opts.profile:

0 commit comments

Comments
 (0)