/* * ===================================================================================== * * Filename: center_main.cc * * Description: * * Version: 1.0 * Created: 2021年04月13日 16时16分26秒 * Revision: none * Compiler: gcc * * Author: Li Chao (), lichao@aiotlink.com * Organization: * * ===================================================================================== */ #include "app_arg.h" #include "box.h" #include "center.h" #include "defs.h" #include "log.h" #include "signalhandle.h" #include #include #include using namespace std::chrono_literals; using namespace bhome_shm; namespace { const std::string kCenterRunningFlag = "bh_center_single_flag_0"; class InstanceFlag { public: InstanceFlag(SharedMemory &shm, const std::string &name) : shm_(shm), name_(name), run_(false) {} ~InstanceFlag() { Stop(); } bool TryStartAsFirstInstance() { if (run_) { return true; } auto mtx(shm_.FindOrCreate(name_ + "_mutex_0")); auto time_stamp(shm_.FindOrCreate(name_ + "_timestamp_0", 0)); if (mtx && time_stamp) { Guard lock(*mtx); auto now = NowSec(); LOG_DEBUG() << "old: " << *time_stamp << ", now: " << now; if (now > *time_stamp + 10) { *time_stamp = now; auto UpdateTime = [this, time_stamp]() { while (run_) { std::this_thread::sleep_for(1s); *time_stamp = NowSec(); } }; run_.store(true); std::thread(UpdateTime).swap(worker_); return true; } } return false; } private: void Stop() { run_.store(false); if (worker_.joinable()) { worker_.join(); } } std::thread worker_; SharedMemory &shm_; std::string name_; std::atomic run_; }; } // namespace int center_main(int argc, const char *argv[]) { AppArg args(argc, argv); if (args.Has("remove")) { SharedMemory::Remove(BHomeShmName()); return 0; } ns_log::AddLog("/opt/vasystem/valog/bhshmq_center.log"); auto lvl = args.Get("log", "info"); if (strcasecmp(lvl.c_str(), "trace") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::trace); } if (strcasecmp(lvl.c_str(), "debug") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::debug); } if (strcasecmp(lvl.c_str(), "info") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::info); } if (strcasecmp(lvl.c_str(), "warning") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::warning); } if (strcasecmp(lvl.c_str(), "error") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::error); } if (strcasecmp(lvl.c_str(), "fatal") == 0) { ns_log::ResetLogLevel(ns_log::LogLevel::fatal); } auto &shm = BHomeShm(); if (!CenterInit(shm)) { auto msg = "init memory error."; LOG_FATAL() << msg; printf("%s\n", msg); exit(0); } GlobalInit(shm); InstanceFlag inst(shm, kCenterRunningFlag); if (!inst.TryStartAsFirstInstance()) { auto msg = "another instance is running, exit."; LOG_INFO() << msg; printf("%s\n", msg); return 0; } if (args.Has("daemon") || args.Has("d")) { int r = daemon(0, 0); // TODO center control msg to close itself. } BHCenter center(shm); center.Start(); auto msg = "center started ..."; LOG_INFO() << msg; printf("%s\n", msg); WaitForSignals({SIGINT, SIGTERM}); center.Stop(); LOG_INFO() << "center stopped."; return 0; } namespace { static bool install = BoxInstall("bhshmq_center", center_main, "bhome center program."); }