mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-10-31 10:50:00 -04:00
Monitor::CheckAction() handled the RELOAD action (zmu --reload, or a script setting it through ZoneMinder::Memory) by calling Reload() in place. That runs on zmc's capture thread, and Monitor::Load() rewrites settings such as label_format, orientation and the image sizes while the decoder and analysis threads read them unlocked. SIGHUP already reloads safely: zmc leaves its capture loop, Close()s and disconnect()s each monitor, which stops those threads, then Reload()s and reconnects. Have the action set zm_reload, as the SIGHUP handler does, so both take that path. zmc reloads every monitor it runs this way, not only the one the action was sent to; zmc normally runs one. Tested live on 1.38 with zmu --reload against a running zmc: the event closes, the same process reloads and reconnects, capture resumes and a new event opens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
60 lines
2.0 KiB
C++
60 lines
2.0 KiB
C++
/*
|
|
* This file is part of the ZoneMinder Project. See AUTHORS file for Copyright information
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "zm_catch2.h"
|
|
|
|
#include "zm_config.h"
|
|
#include "zm_monitor.h"
|
|
#include "zm_signal.h"
|
|
|
|
namespace {
|
|
|
|
void EnsureConfig() {
|
|
if (!config.font_file_location) config.font_file_location = "";
|
|
if (!config.event_close_mode) config.event_close_mode = "idle";
|
|
}
|
|
|
|
// A Monitor whose shared data is a local struct instead of the mapping, so
|
|
// CheckAction() can be driven without connect().
|
|
class ActionMonitor : public Monitor {
|
|
public:
|
|
using Data = SharedData;
|
|
static constexpr int kReload = RELOAD;
|
|
explicit ActionMonitor(SharedData *data) : Monitor() { shared_data = data; }
|
|
~ActionMonitor() { shared_data = nullptr; }
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// The reload action (zmu --reload) used to run Reload() right there, on zmc's
|
|
// capture thread, rewriting the monitor's settings while the decoder and
|
|
// analysis threads read them. It now asks for the reload SIGHUP does, which
|
|
// zmc carries out after Close() has stopped those threads. refs #5239
|
|
TEST_CASE("Monitor reload action defers to zmc's reload", "[Monitor]") {
|
|
EnsureConfig();
|
|
ActionMonitor::Data data = {};
|
|
data.action = ActionMonitor::kReload;
|
|
ActionMonitor monitor(&data);
|
|
|
|
zm_reload = false;
|
|
monitor.CheckAction();
|
|
|
|
REQUIRE(zm_reload);
|
|
REQUIRE((data.action & ActionMonitor::kReload) == 0);
|
|
zm_reload = false;
|
|
}
|