From 071756ac218bbb26e8c4215541bc96b72a77c086 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:15:37 +0800 Subject: [PATCH] gmoccapy: handle SIGTERM/SIGINT regardless of main-loop state The KeyboardInterrupt-via-excepthook path only quits while Gtk.main() is iterating; a signal during startup or a nested dialog hits 'gtk_main_quit: assertion main_loops != NULL' and gmoccapy runs on until SIGKILL. Install an explicit handler that quits the loop if one runs, else exits the process. --- src/emc/usr_intf/gmoccapy/gmoccapy.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/emc/usr_intf/gmoccapy/gmoccapy.py b/src/emc/usr_intf/gmoccapy/gmoccapy.py index 86c2ed28a5d..db03bdd7e9a 100644 --- a/src/emc/usr_intf/gmoccapy/gmoccapy.py +++ b/src/emc/usr_intf/gmoccapy/gmoccapy.py @@ -40,6 +40,7 @@ from common import hal_glib # needed to make our own hal pins import sys # handle system calls import os # needed to get the paths and directories +import signal # clean shutdown on SIGTERM/SIGINT import atexit # needed to register child's to be closed on closing the GUI import subprocess # to launch onboard and other processes import tempfile # needed only if the user click new in edit mode to open a new empty file @@ -6594,6 +6595,18 @@ def _make_hal_pins(self): raise SystemExit(res) + # Exit on SIGTERM/SIGINT whether or not a main loop is running. + # Gtk.main_quit() does nothing outside a running loop, so quit the + # loop if one is active, otherwise exit the process. + def _terminate(signum, frame): + LOG.info("gmoccapy received signal {}, shutting down".format(signum)) + if Gtk.main_level() > 0: + Gtk.main_quit() + else: + sys.exit(0) + signal.signal(signal.SIGTERM, _terminate) + signal.signal(signal.SIGINT, _terminate) + # start the event loop Gtk.main()