vendor_base.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "vendor_base.h"
  2. #include "vendor_global.h"
  3. #include <event.h>
  4. #include <signal.h>
  5. namespace vendor {
  6. struct event_base *eventBase_ = nullptr;
  7. LongOpts::LongOpts(const MyOpt opts[], const int size)
  8. {
  9. myOpt = opts;
  10. sizeOpt = size;
  11. }
  12. void LongOpts::GetOptions(option *opts, std::string &shorts)
  13. {
  14. for (int i = 0; i < sizeOpt; i++) {
  15. // printf("val: %d(%c) ", myOpt[i].val, myOpt[i].val);
  16. opts[i].name = strdup(myOpt[i].name);
  17. opts[i].has_arg = myOpt[i].has_arg;
  18. opts[i].flag = NULL;
  19. opts[i].val = myOpt[i].val;
  20. if (myOpt[i].val == 0) {
  21. continue;
  22. }
  23. if (myOpt[i].has_arg == no_argument) {
  24. shorts.push_back(static_cast<char>(myOpt[i].val));
  25. } else if (myOpt[i].has_arg == required_argument) {
  26. shorts.push_back(static_cast<char>(myOpt[i].val));
  27. shorts.push_back(':');
  28. } else {
  29. shorts.push_back(static_cast<char>(myOpt[i].val));
  30. }
  31. }
  32. }
  33. MyOpt LongOpts::GetOption(char ch, int index)
  34. {
  35. if (ch == 0) {
  36. return myOpt[index];
  37. }
  38. for (int i = 0; i < sizeOpt; i++) {
  39. if (myOpt[i].val == ch) {
  40. return myOpt[i];
  41. }
  42. }
  43. return myOpt[0];
  44. }
  45. VendorBase::VendorBase()
  46. {
  47. HTELINK_LOG_ENABLE(true);
  48. eventBase_ = event_base_new();
  49. if (eventBase_ == nullptr) {
  50. HTELINK_LOG_ERR("event new failed, %s", strerror(errno));
  51. }
  52. }
  53. VendorBase::~VendorBase()
  54. {
  55. if (eventBase_ == nullptr) {
  56. return;
  57. }
  58. Exit(SIGINT);
  59. event_base_free(eventBase_);
  60. }
  61. int VendorBase::Exec()
  62. {
  63. HTELINK_LOG_INFO("register event...");
  64. // 注册信号事件
  65. event_add(evsignal_new(eventBase_, SIGSEGV, VendorBase::SignalHandler, this), NULL);
  66. event_add(evsignal_new(eventBase_, SIGFPE, VendorBase::SignalHandler, this), NULL);
  67. event_add(evsignal_new(eventBase_, SIGINT, VendorBase::SignalHandler, this), NULL);
  68. event_add(evsignal_new(eventBase_, SIGTERM, VendorBase::SignalHandler, this), NULL);
  69. event_add(evsignal_new(eventBase_, SIGTSTP, VendorBase::SignalHandler, this), NULL);
  70. signal(SIGPIPE, SIG_IGN);
  71. HTELINK_LOG_INFO("start to Run");
  72. // struct event *timer_ev = event_new(
  73. // eventBase_, -1, EV_PERSIST,
  74. // [](evutil_socket_t ev, short e, void *arg) {
  75. // VendorBase *vendorBase = static_cast<VendorBase *>(arg);
  76. // vendorBase->Run();
  77. // },
  78. // this);
  79. // event_add(timer_ev, NULL);
  80. std::thread fn([this] {
  81. Run();
  82. });
  83. fn.detach();
  84. // 其他业务
  85. HTELINK_LOG_INFO("start to deamon...");
  86. return event_base_dispatch(eventBase_);
  87. }
  88. void VendorBase::Exit(int signal)
  89. {
  90. Stop(signal);
  91. if (eventBase_ == nullptr) {
  92. return;
  93. }
  94. char dumpFile[VENDOR_MAX_PATH_SIZE];
  95. sprintf(dumpFile, "%s/event_stat_%s.txt", VENDOR_LOG_PATH.c_str(), utils::nowtostr().c_str());
  96. FILE *fp = fopen(dumpFile, "a");
  97. event_base_dump_events(eventBase_, fp);
  98. fclose(fp);
  99. event_base_loopbreak(eventBase_);
  100. }
  101. void VendorBase::SignalHandler(int fd, short event, void *arg)
  102. {
  103. if (event != EV_SIGNAL) {
  104. HTELINK_LOG_ERR("fd: %d, event: %d occur", fd, event);
  105. return;
  106. }
  107. void *l_buffer[512];
  108. char **l_ptrace;
  109. int signal = fd;
  110. VendorBase *vendorBase = static_cast<VendorBase *>(arg);
  111. if (vendorBase) {
  112. vendorBase->Exit(signal);
  113. }
  114. HTELINK_LOG_ERR("\r\n=========>>>catch signal %d <<<=========", signal);
  115. HTELINK_LOG_ERR("Dump stack start...");
  116. int size = backtrace(l_buffer, 512);
  117. l_ptrace = backtrace_symbols(l_buffer, size);
  118. if (NULL == l_ptrace) {
  119. HTELINK_LOG_ERR("backtrace_symbols");
  120. exit(1);
  121. }
  122. for (int i = 0; i < size; i++) {
  123. HTELINK_LOG_ERR(" [%02d] %s", i, l_ptrace[i]);
  124. }
  125. HTELINK_LOG_ERR("Dump stack end...");
  126. free(l_ptrace);
  127. exit(signal);
  128. }
  129. int32_t VendorBase::ParseOptionArgs(VendorBase *vendor, int argc, char *argv[])
  130. {
  131. int longindex = 0;
  132. std::string shorts;
  133. struct option longopts[vendor->GetOptSize()];
  134. LongOpts longOpts(vendor->GetOpts(), vendor->GetOptSize());
  135. longOpts.GetOptions(longopts, shorts);
  136. int ch;
  137. while ((ch = getopt_long(argc, argv, shorts.c_str(), longopts, &longindex)) != -1) {
  138. MyOpt myOpt = longOpts.GetOption(ch, longindex);
  139. printf("longindex :%d, opt %d(%c), name:%s , optarg :%s\n", longindex, myOpt.val, myOpt.val, myOpt.name,
  140. optarg == nullptr ? "nullptr" : optarg);
  141. if (strcmp(myOpt.name, "help") == 0) {
  142. MyOpt *myOpts = vendor->GetOpts();
  143. printf("Usage: %s [OPTION] -l URL\n\nOPTIONS:\n", vendor->Name().c_str());
  144. for (int i = 1; i < vendor->GetOptSize(); i++) {
  145. if (myOpts[i].val == 0) {
  146. printf("--%s: %s\n", myOpts[i].name, myOpts[i].desc);
  147. } else {
  148. printf("-%c, --%s: %s\n", myOpts[i].val, myOpts[i].name, myOpts[i].desc);
  149. }
  150. }
  151. return -1;
  152. }
  153. if (vendor->ParseCmdline(myOpt.name, optarg == nullptr ? "" : optarg) != 0) {
  154. printf("parse failed!!!\n");
  155. return -1;
  156. }
  157. }
  158. return 0;
  159. }
  160. }; // namespace vendor