oresat / oresat-c3-software

Main application for Octavo A8 version of the C3 card
https://oresat-c3-software.readthedocs.io/en/latest/
GNU General Public License v3.0
2 stars 1 forks source link

Mark watchdog thread daemonic #16

Closed ThirteenFish closed 8 months ago

ThirteenFish commented 8 months ago

A python application will only quit when all non-daemonic threads have stopped. The watchdog thread is non-daemonic and so oresat_c3 can only quit once the watchdog thread has stopped. The watchdog thread will only quit if event is set, and event only gets set if oresat_c3 successfully makes it to the end of main().

If oresat_c3 doesn't make it successfully to the end of main() (say an exception occurs during service initialization) then the watchdog thread will never stop, even though the main thread has, keeping the application running in a sort of unresponsive zombie mode. It is in fact so unresponsive that it ignores SIGINT (ctrl-c) so the only way to get it to stop is a SIGKILL, which is uncouth.

Daemonic threads on the other hand will stop abruptly when the last non-daemon thread stops. This can be bad if resources in the thread need finalization but the only resource in the watchdog thread is a UDP socket, which the kernel will helpfully close for us. Setting the daemonic flag on the watchdog thread allows oresat_c3 to stop gracefully in exceptional circumstances.

An alternative to daemonic threads would be to wrap everything after starting the thread in a try-finally block but I felt that would be a bit more intrusive.