@@ -75,6 +75,7 @@ def recv_json_with_retry(self):
7575
7676# Global ZeroMQ ports registry
7777zmq_ports = {}
78+ _cleanup_in_progress = False
7879
7980def init_zmq_port (port_name , port_type , address , socket_type_str ):
8081 """
@@ -102,9 +103,15 @@ def init_zmq_port(port_name, port_type, address, socket_type_str):
102103
103104def terminate_zmq ():
104105 """Clean up all ZMQ sockets and contexts before exit."""
106+ global _cleanup_in_progress
107+
108+ if _cleanup_in_progress :
109+ return # Already cleaning up, prevent reentrant calls
110+
105111 if not zmq_ports :
106112 return # No ports to clean up
107113
114+ _cleanup_in_progress = True
108115 print ("\n Cleaning up ZMQ resources..." )
109116 for port_name , port in zmq_ports .items ():
110117 try :
@@ -114,17 +121,25 @@ def terminate_zmq():
114121 except Exception as e :
115122 logging .error (f"Error while terminating ZMQ port { port .address } : { e } " )
116123 zmq_ports .clear ()
124+ _cleanup_in_progress = False
117125
118126def signal_handler (sig , frame ):
119127 """Handle interrupt signals gracefully."""
120128 print (f"\n Received signal { sig } , shutting down gracefully..." )
129+ # Prevent terminate_zmq from being called twice: once here and once via atexit
130+ try :
131+ atexit .unregister (terminate_zmq )
132+ except Exception :
133+ # If unregister fails for any reason, proceed with explicit cleanup anyway
134+ pass
121135 terminate_zmq ()
122136 sys .exit (0 )
123137
124138# Register cleanup handlers
125139atexit .register (terminate_zmq )
126140signal .signal (signal .SIGINT , signal_handler ) # Handle Ctrl+C
127- signal .signal (signal .SIGTERM , signal_handler ) # Handle termination
141+ if not hasattr (sys , 'getwindowsversion' ):
142+ signal .signal (signal .SIGTERM , signal_handler ) # Handle termination (Unix only)
128143
129144# --- ZeroMQ Integration End ---
130145
0 commit comments