Fix #214: Prevent ToolManager crash callback deadlock

- Move crash_callback execution outside of self._lock
- Callback is called after releasing the monitor lock
- Re-acquire lock only for restart decision logic
- Prevents deadlock if callback tries to acquire same lock
- Maintains thread safety for restart and process state updates
This commit is contained in:
Cobra
2026-04-06 11:40:36 -04:00
parent 1b93378f02
commit f15b8994cd
+9 -4
View File
@@ -336,13 +336,19 @@ class ToolManager:
"restart_count": tool.restart_count},
source_module="tool_manager")
# Crash callback (e.g., corrective ARP)
if tool.crash_callback:
# Call crash callback OUTSIDE lock to prevent deadlock
callback = tool.crash_callback
restart_needed = tool.restart_count < tool.max_restarts
# Release lock before callback
if callback:
try:
tool.crash_callback()
callback()
except Exception:
logger.exception("Crash callback failed for %s", tool.name)
# Re-acquire lock for restart decision
with self._lock:
# Auto-restart with exponential backoff
if tool.restart_count < tool.max_restarts:
backoff = min(2 ** tool.restart_count, 30)
@@ -351,7 +357,6 @@ class ToolManager:
tool.max_restarts)
time.sleep(backoff)
tool.restart_count += 1
with self._lock:
self._start_tool(tool)
else:
logger.error("Tool %s exceeded max restarts (%d), giving up",