The old ColdMutex (interprocess_mutex) was in process-local anonymous
namespace storage, so each process had its own copy — no actual
cross-process exclusion. Even if moved to SHM, interprocess_mutex is
not robust: a crash while holding the lock would deadlock on restart.
New design:
- ShmSpinLock: atomic<pid_t> in shared memory, kill(pid,0) detects
dead owners (ESRCH → takeover), crash-safe by construction
- std::mutex: process-local, handles intra-process thread contention
without burning CPU on the SHM spinlock
- DualLock: locks local first, then shm; unlocks in reverse
9 lock sites in MapRuleStat upgraded to std::lock_guard<DualLock>.
Display data (alarm_value, current_value, limit_up/down, items, unit) now
goes to a local-memory DisplayCache and is serialized to JSON without any
shared memory lock. Cold data (stat_values, running_time, shear_times, etc.)
stays in shared memory for mon-cron IPC, protected by a real interprocess
mutex (boost::interprocess::interprocess_mutex) instead of the broken
process-local std::mutex. AlgBase::rule_stat_ is now RuleStatLocal with
standard types — zero changes to algorithm subclass code.