| | |
| | | utest/utest |
| | | *.bak |
| | | gmon.out |
| | | box/bhshmqbox |
| | | box/bhshmq_center |
| | | box/help |
| | |
| | | |
| | | 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) |
| | | |
New file |
| | |
| | | |
| | | 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}) |
New file |
| | |
| | | /* |
| | | * ===================================================================================== |
| | | * |
| | | * 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); |
| | | } |
New file |
| | |
| | | /* |
| | | * ===================================================================================== |
| | | * |
| | | * 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 |
New file |
| | |
| | | /* |
| | | * ===================================================================================== |
| | | * |
| | | * 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."); |
| | | } |
New file |
| | |
| | | #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; |
| | | } |
| | | |
New file |
| | |
| | | #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 |
| | |
| | | |
| | | file(GLOB sources "./*.cpp") |
| | | |
| | | set(Target bhshm) |
| | | set(Target bhome_shmq) |
| | | |
| | | add_library(${Target} ${sources}) |
| | | |
| | |
| | | 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) |