123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include "vendor_base.h"
- #include "vendor_global.h"
- #include <event.h>
- #include <signal.h>
- namespace vendor {
- struct event_base *eventBase_ = nullptr;
- LongOpts::LongOpts(const MyOpt opts[], const int size)
- {
- myOpt = opts;
- sizeOpt = size;
- }
- void LongOpts::GetOptions(option *opts, std::string &shorts)
- {
- for (int i = 0; i < sizeOpt; i++) {
- // printf("val: %d(%c) ", myOpt[i].val, myOpt[i].val);
- opts[i].name = strdup(myOpt[i].name);
- opts[i].has_arg = myOpt[i].has_arg;
- opts[i].flag = NULL;
- opts[i].val = myOpt[i].val;
- if (myOpt[i].val == 0) {
- continue;
- }
- if (myOpt[i].has_arg == no_argument) {
- shorts.push_back(static_cast<char>(myOpt[i].val));
- } else if (myOpt[i].has_arg == required_argument) {
- shorts.push_back(static_cast<char>(myOpt[i].val));
- shorts.push_back(':');
- } else {
- shorts.push_back(static_cast<char>(myOpt[i].val));
- }
- }
- }
- MyOpt LongOpts::GetOption(char ch, int index)
- {
- if (ch == 0) {
- return myOpt[index];
- }
- for (int i = 0; i < sizeOpt; i++) {
- if (myOpt[i].val == ch) {
- return myOpt[i];
- }
- }
- return myOpt[0];
- }
- VendorBase::VendorBase()
- {
- HTELINK_LOG_ENABLE(true);
- eventBase_ = event_base_new();
- if (eventBase_ == nullptr) {
- HTELINK_LOG_ERR("event new failed, %s", strerror(errno));
- }
- }
- VendorBase::~VendorBase()
- {
- if (eventBase_ == nullptr) {
- return;
- }
- Exit(SIGINT);
- event_base_free(eventBase_);
- }
- int VendorBase::Exec()
- {
- HTELINK_LOG_INFO("register event...");
- // 注册信号事件
- event_add(evsignal_new(eventBase_, SIGSEGV, VendorBase::SignalHandler, this), NULL);
- event_add(evsignal_new(eventBase_, SIGFPE, VendorBase::SignalHandler, this), NULL);
- event_add(evsignal_new(eventBase_, SIGINT, VendorBase::SignalHandler, this), NULL);
- event_add(evsignal_new(eventBase_, SIGTERM, VendorBase::SignalHandler, this), NULL);
- event_add(evsignal_new(eventBase_, SIGTSTP, VendorBase::SignalHandler, this), NULL);
- signal(SIGPIPE, SIG_IGN);
- HTELINK_LOG_INFO("start to Run");
- // struct event *timer_ev = event_new(
- // eventBase_, -1, EV_PERSIST,
- // [](evutil_socket_t ev, short e, void *arg) {
- // VendorBase *vendorBase = static_cast<VendorBase *>(arg);
- // vendorBase->Run();
- // },
- // this);
- // event_add(timer_ev, NULL);
- std::thread fn([this] {
- Run();
- });
- fn.detach();
- // 其他业务
- HTELINK_LOG_INFO("start to deamon...");
- return event_base_dispatch(eventBase_);
- }
- void VendorBase::Exit(int signal)
- {
- Stop(signal);
- if (eventBase_ == nullptr) {
- return;
- }
- char dumpFile[VENDOR_MAX_PATH_SIZE];
- sprintf(dumpFile, "%s/event_stat_%s.txt", VENDOR_LOG_PATH.c_str(), utils::nowtostr().c_str());
- FILE *fp = fopen(dumpFile, "a");
- event_base_dump_events(eventBase_, fp);
- fclose(fp);
- event_base_loopbreak(eventBase_);
- }
- void VendorBase::SignalHandler(int fd, short event, void *arg)
- {
- if (event != EV_SIGNAL) {
- HTELINK_LOG_ERR("fd: %d, event: %d occur", fd, event);
- return;
- }
- void *l_buffer[512];
- char **l_ptrace;
- int signal = fd;
- VendorBase *vendorBase = static_cast<VendorBase *>(arg);
- if (vendorBase) {
- vendorBase->Exit(signal);
- }
- HTELINK_LOG_ERR("\r\n=========>>>catch signal %d <<<=========", signal);
- HTELINK_LOG_ERR("Dump stack start...");
- int size = backtrace(l_buffer, 512);
- l_ptrace = backtrace_symbols(l_buffer, size);
- if (NULL == l_ptrace) {
- HTELINK_LOG_ERR("backtrace_symbols");
- exit(1);
- }
- for (int i = 0; i < size; i++) {
- HTELINK_LOG_ERR(" [%02d] %s", i, l_ptrace[i]);
- }
- HTELINK_LOG_ERR("Dump stack end...");
- free(l_ptrace);
- exit(signal);
- }
- int32_t VendorBase::ParseOptionArgs(VendorBase *vendor, int argc, char *argv[])
- {
- int longindex = 0;
- std::string shorts;
- struct option longopts[vendor->GetOptSize()];
- LongOpts longOpts(vendor->GetOpts(), vendor->GetOptSize());
- longOpts.GetOptions(longopts, shorts);
- int ch;
- while ((ch = getopt_long(argc, argv, shorts.c_str(), longopts, &longindex)) != -1) {
- MyOpt myOpt = longOpts.GetOption(ch, longindex);
- printf("longindex :%d, opt %d(%c), name:%s , optarg :%s\n", longindex, myOpt.val, myOpt.val, myOpt.name,
- optarg == nullptr ? "nullptr" : optarg);
- if (strcmp(myOpt.name, "help") == 0) {
- MyOpt *myOpts = vendor->GetOpts();
- printf("Usage: %s [OPTION] -l URL\n\nOPTIONS:\n", vendor->Name().c_str());
- for (int i = 1; i < vendor->GetOptSize(); i++) {
- if (myOpts[i].val == 0) {
- printf("--%s: %s\n", myOpts[i].name, myOpts[i].desc);
- } else {
- printf("-%c, --%s: %s\n", myOpts[i].val, myOpts[i].name, myOpts[i].desc);
- }
- }
- return -1;
- }
- if (vendor->ParseCmdline(myOpt.name, optarg == nullptr ? "" : optarg) != 0) {
- printf("parse failed!!!\n");
- return -1;
- }
- }
- return 0;
- }
- }; // namespace vendor
|