From 856cb250e56520de7eab6874a46fb7d4386d1b6a Mon Sep 17 00:00:00 2001 From: Nic Boet Date: Mon, 12 Oct 2026 09:47:18 -0500 Subject: [PATCH] fix: close and disconnect zmc's monitors when stopped during startup A SIGTERM while zmc is still connecting or priming its monitors broke out of the outer loop at the "if (zm_terminate) break;" after the startup loop, skipping the Close()/disconnect() loop. Monitors that had connected kept their decoder, analysis, poller and ONVIF threads running through dbQueue.stop(), zmDbClose() and logTerm() at the end of main, and were never destroyed: each Zone holds a shared_ptr to its Monitor and only disconnect() clears the zones. Drop that break. With zm_terminate set the capture loop doesn't run, so the Close()/disconnect() loop runs next and the outer loop ends as it does on a normal stop. Close() and disconnect() already run on monitors that never connected or are already disconnected (reconnects do that). fixes #5220 Co-Authored-By: Claude Opus 5.5 --- src/zmc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zmc.cpp b/src/zmc.cpp index 0ef3be68cb..9a8fe7044d 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -325,7 +325,9 @@ int main(int argc, char *argv[]) { zmDbDo(sql); } // end foreach monitor - if (zm_terminate) break; + // No break on zm_terminate here: the capture loop below doesn't run then, + // and the Close()/disconnect() loop after it must, or the monitors started + // so far keep their threads and are never freed (their zones hold them). std::vector last_capture_times = std::vector(monitors.size()); Microseconds sleep_time = Microseconds(0);