From 047f801078a52042ef02750b577233d115ed0f57 Mon Sep 17 00:00:00 2001 From: lichao <lichao@aiotlink.com> Date: 星期二, 13 四月 2021 17:12:25 +0800 Subject: [PATCH] rename library, add box. --- box/center_main.cc | 35 +++++ .gitignore | 3 box/center.cpp | 0 box/signalhandle.h | 41 ++++++ src/CMakeLists.txt | 2 box/CMakeLists.txt | 15 ++ box/center.h | 0 utest/CMakeLists.txt | 2 box/box.h | 27 ++++ CMakeLists.txt | 2 box/signalhandle.cpp | 70 +++++++++++ box/box.cc | 134 ++++++++++++++++++++++ 12 files changed, 329 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 8e81403..d6ac3de 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ utest/utest *.bak gmon.out +box/bhshmqbox +box/bhshmq_center +box/help diff --git a/CMakeLists.txt b/CMakeLists.txt index 23f3ce7..fa3cc44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,9 @@ add_subdirectory(${PROJECT_SOURCE_DIR}/proto/cpp proto) include_directories(${CMAKE_CURRENT_BINARY_DIR}/proto) +include_directories(${PROJECT_SOURCE_DIR}/box) add_subdirectory(${PROJECT_SOURCE_DIR}/src) +add_subdirectory(${PROJECT_SOURCE_DIR}/box) add_subdirectory(${PROJECT_SOURCE_DIR}/utest) diff --git a/box/CMakeLists.txt b/box/CMakeLists.txt new file mode 100644 index 0000000..3ecb694 --- /dev/null +++ b/box/CMakeLists.txt @@ -0,0 +1,15 @@ + +file(GLOB lib_sources "./*.cpp") +file(GLOB exe_sources "./*.cc") + +set(Target bhshmqbox) +set(BinTarget ${Target}-bin) + +include_directories(../src) +add_library(${Target} ${lib_sources}) +add_executable(${BinTarget} ${exe_sources}) + +target_link_libraries(${Target} bhome_shmq bhome_msg pthread rt) +target_link_libraries(${BinTarget} ${Target} boost_filesystem ) +set_target_properties(${BinTarget} + PROPERTIES OUTPUT_NAME ${Target}) diff --git a/box/box.cc b/box/box.cc new file mode 100644 index 0000000..dab1c42 --- /dev/null +++ b/box/box.cc @@ -0,0 +1,134 @@ +/* + * ===================================================================================== + * + * Filename: box.cpp + * + * Description: + * + * Version: 1.0 + * Created: 2021骞�04鏈�13鏃� 15鏃�21鍒�44绉� + * Revision: none + * Compiler: gcc + * + * Author: Li Chao (), lichao@aiotlink.com + * Organization: + * + * ===================================================================================== + */ +#include "box.h" +#include <boost/filesystem/path.hpp> +#include <map> +#include <unordered_map> + +namespace fs = boost::filesystem; + +namespace +{ + +class Box +{ +public: + bool Install(const std::string &name, MainFunc const &func, const std::string &desc) + { + return functions_.emplace(name, FuncInfo{name, func, desc}).second; + } + bool Find(const std::string &name, MainFunc &func) + { + auto pos = functions_.find(name); + if (pos != functions_.end()) { + func = pos->second.func_; + return true; + } + return false; + } + void Apply(std::function<void(const std::string &id, const std::string &desc)> f) const + { + for (auto &kv : functions_) { + f(kv.second.id_, kv.second.desc_); + } + } + +private: + struct FuncInfo { + std::string id_; + MainFunc func_; + std::string desc_; + }; + std::unordered_map<std::string, FuncInfo> functions_; +}; + +Box &TheBox() +{ + static Box box; + return box; +} + +} // namespace + +bool BoxInstall(const std::string &name, MainFunc const &func, const std::string &desc) +{ + return TheBox().Install(name, func, desc); +} + +bool BoxFind(const std::string &name, MainFunc &func) +{ + return TheBox().Find(name, func); +} + +const std::string kOrigName("bhshmqbox"); +void Help() +{ + printf("%s : bhome shared memory message queue box application.\n", kOrigName.c_str()); + printf("usage:\n"); + printf("\t1) %s [function [options]...]\n", kOrigName.c_str()); + printf("\t2) rename or link %s to a function name then run it directly.\n", kOrigName.c_str()); + printf("\nsupported functions:\n"); + std::map<std::string, std::string> funcs; + auto getInfo = [&](const std::string &name, const std::string &desc) { + funcs[name] = desc; + }; + TheBox().Apply(getInfo); + auto cmp_name_len = [](auto &a, auto &b) { return a.first.size() < b.first.size(); }; + int max_len = std::max_element(funcs.begin(), funcs.end(), cmp_name_len)->first.size(); + for (auto &kv : funcs) { + int npad = max_len - kv.first.size(); + printf("\n\t%s%s : %s\n", kv.first.c_str(), std::string(npad, ' ').c_str(), kv.second.c_str()); + } + printf("\n"); +} + +int BoxMain(int argc, const char *argv[]) +{ + fs::path exe(argv[0]); + auto name = exe.filename().string(); + + MainFunc func; + if (BoxFind(name, func)) { + return func(argc, argv); + } else { + printf("%s : function not found!\n", name.c_str()); + // Help(); + } + return 0; +} + +int main(int argc, const char *argv[]) +{ + BoxInstall( + "help", [](int, const char **) { Help(); return 0; }, "show this help message."); + + fs::path exe(argv[0]); + auto name = exe.filename().string(); + // printf("name: %s\n", name.c_str()); + + if (name == kOrigName) { + if (argc > 1) { + argc--; + argv++; + } else { + Help(); + return 0; + } + } + return BoxMain(argc, argv); +} \ No newline at end of file diff --git a/box/box.h b/box/box.h new file mode 100644 index 0000000..14c19f4 --- /dev/null +++ b/box/box.h @@ -0,0 +1,27 @@ +/* + * ===================================================================================== + * + * Filename: box.h + * + * Description: + * + * Version: 1.0 + * Created: 2021骞�04鏈�13鏃� 16鏃�12鍒�44绉� + * Revision: none + * Compiler: gcc + * + * Author: Li Chao (), lichao@aiotlink.com + * Organization: + * + * ===================================================================================== + */ +#ifndef BOX_L3FWJE7T +#define BOX_L3FWJE7T +#include <functional> +#include <string> + +typedef std::function<int(int, const char *argv[])> MainFunc; +bool BoxInstall(const std::string &name, MainFunc const &func, const std::string &desc); +bool BoxFind(const std::string &name, MainFunc &func); + +#endif // end of include guard: BOX_L3FWJE7T diff --git a/src/center.cpp b/box/center.cpp similarity index 100% rename from src/center.cpp rename to box/center.cpp diff --git a/src/center.h b/box/center.h similarity index 100% rename from src/center.h rename to box/center.h diff --git a/box/center_main.cc b/box/center_main.cc new file mode 100644 index 0000000..40aed56 --- /dev/null +++ b/box/center_main.cc @@ -0,0 +1,35 @@ +/* + * ===================================================================================== + * + * 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 "box.h" +#include "center.h" +#include "defs.h" +#include "signalhandle.h" + +int center_main(int argc, const char *argv[]) +{ + BHCenter center(BHomeShm()); + center.Start(); + WaitForSignals({SIGINT, SIGTERM}); + // BHomeShm().Remove(); // remove ? + return 0; +} + +namespace +{ +static bool install = BoxInstall("bhshmq_center", center_main, "bhome center program."); +} diff --git a/box/signalhandle.cpp b/box/signalhandle.cpp new file mode 100755 index 0000000..5d37787 --- /dev/null +++ b/box/signalhandle.cpp @@ -0,0 +1,70 @@ +#include "signalhandle.h" +#include <errno.h> +#include <mutex> +#include <condition_variable> +#include <atomic> +#include <map> + +int CatchSignals(const int signals[], size_t count, void (* signal_handler)(int)) +{ + if (nullptr == signals || 0 == count || nullptr == signal_handler) { + return EINVAL; // Invalid argument (POSIX.1) + } + + struct sigaction action = {0}; + + action.sa_handler = signal_handler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + + for (size_t i = 0; i < count; ++ i) { + if (0 != sigaction(signals[i], &action, nullptr)) { + return errno; + } + } + + return 0; +} + +int CatchSignals(const int signals[], const size_t count, SigFunc f) +{ + struct _ { + typedef std::map<int, SigFunc> SFMap; + static SFMap &Funcs() { static SFMap m; return m; } + static void OnSig(int sig) { + auto pf = Funcs().find(sig); + if (pf != Funcs().end() && pf->second) { + pf->second(sig); + } + } + }; + + for (int i = 0; i < int(count); ++i) { + _::Funcs()[signals[i]] = f; + } + + return CatchSignals(signals, count, &_::OnSig); +} + +int WaitForSignals(const int signals[], const size_t count, SigFunc f) +{ + std::mutex mtx; + std::condition_variable cv; + auto OnSig = [&](int sig) { + static std::atomic<bool> first(true); + if (first.exchange(false)) { + std::unique_lock<std::mutex> guard(mtx); + if (f) { f(sig); } + cv.notify_one(); + } + }; + + std::unique_lock<std::mutex> guard(mtx); + + const int r = CatchSignals(signals, count, OnSig); + if (r == 0) { // register handler. + cv.wait(guard); + } + return r; +} + diff --git a/box/signalhandle.h b/box/signalhandle.h new file mode 100755 index 0000000..3d89e84 --- /dev/null +++ b/box/signalhandle.h @@ -0,0 +1,41 @@ +#ifndef SIGNALHANDLE_WNM4OBKG +#define SIGNALHANDLE_WNM4OBKG + +#include <signal.h> +#include <functional> +#include <vector> + +typedef std::function<void (int)> SigFunc; +// return 0 on success. +int CatchSignals(const int signals[], const size_t count, SigFunc f); +int WaitForSignals(const int signals[], const size_t count, SigFunc f = SigFunc()); + +template <size_t N> inline +int CatchSignals(const int (& signals)[N], SigFunc f) { + return CatchSignals(signals, N, f); +} + +template <class ...T> inline +void CatchSignals(std::initializer_list<int> list, T...t) +{ + std::vector<int> arr(list.begin(), list.end()); + CatchSignals(arr.data(), arr.size(), t...); +} + +template <size_t N> inline +int WaitForSignals(const int (&signals)[N]) { + return WaitForSignals(signals, N, SigFunc()); +} + +template <size_t N, class Func> inline +int WaitForSignals(int (&signals)[N], Func f) { + return WaitForSignals(signals, N, f); +} + +template <class ...T> inline +void WaitForSignals(std::initializer_list<int> list, T...t) +{ + std::vector<int> arr(list.begin(), list.end()); + WaitForSignals(arr.data(), arr.size(), t...); +} +#endif // end of include guard: SIGNALHANDLE_WNM4OBKG diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1db0086..b17a2f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ file(GLOB sources "./*.cpp") -set(Target bhshm) +set(Target bhome_shmq) add_library(${Target} ${sources}) diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index 23ca913..4992516 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -4,4 +4,4 @@ include_directories(../src) add_executable(utest ${sources}) -target_link_libraries(utest bhshm boost_test_exec_monitor boost_unit_test_framework boost_timer boost_chrono) +target_link_libraries(utest bhshmqbox boost_test_exec_monitor boost_unit_test_framework boost_timer boost_chrono) -- Gitblit v1.8.0