123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #include "vendor_base.h"
- #include "vendor_global.h"
- #include <errno.h>
- #include <pthread.h>
- #include <signal.h>
- #include <string.h>
- #include <utils/logger.h>
- namespace vendor {
- 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);
- uvLoop_ = uv_default_loop();
- if (uvLoop_ == nullptr) {
- HTELINK_LOG_ERR("event new failed, %s", strerror(errno));
- }
- }
- VendorBase::~VendorBase()
- {
- if (uvLoop_ == nullptr) {
- return;
- }
- for (auto sig : uvSignals_) {
- uv_close(reinterpret_cast<uv_handle_t *>(sig), nullptr);
- delete sig;
- }
- uvSignals_.clear();
- uv_loop_close(uvLoop_);
- Exit(SIGINT);
- }
- void VendorBase::ListenSignal(int signal)
- {
- uv_signal_t *uvSigal = new uv_signal_t;
- uv_signal_init(uvLoop_, uvSigal);
- uvSigal->data = this;
- uv_signal_start(uvSigal, VendorBase::SignalHandler, signal);
- uvSignals_.push_back(reinterpret_cast<uv_handle_t *>(uvSigal));
- }
- int VendorBase::Exec()
- {
- HTELINK_LOG_INFO("register event...");
- // 注册信号事件
- ListenSignal(SIGSEGV);
- ListenSignal(SIGFPE);
- ListenSignal(SIGINT);
- ListenSignal(SIGTERM);
- #ifndef WIN32
- ListenSignal(SIGTSTP);
- signal(SIGPIPE, SIG_IGN);
- #endif
- AppendTimerEvent(10 * 60 * 1000, [] {
- /* move files if disk full */
- utils::check_disk_log(VENDOR_LOG_PATH);
- });
- uv_work_t workReq;
- workReq.data = this;
- uv_queue_work(
- uvLoop_, &workReq,
- [](uv_work_t *req) {
- VendorBase *vb = reinterpret_cast<VendorBase *>(req->data);
- HTELINK_LOG_INFO("start to Run");
- vb->Run();
- },
- [](uv_work_t *req, int status) {});
- HTELINK_LOG_INFO("start to deamon...");
- return uv_run(uvLoop_, UV_RUN_DEFAULT);
- }
- void VendorBase::Exit(int signal)
- {
- Stop(signal);
- if (uvLoop_ == nullptr) {
- return;
- }
- uv_stop(uvLoop_);
- }
- uv_handle_t *VendorBase::AppendEvent(int fd, int ev, VendorIf *vif)
- {
- uv_async_t *async = new uv_async_t;
- uv_async_cb asyncCb = [](uv_async_t *handle) {
- VendorIf *vif = static_cast<VendorIf *>(handle->data);
- if (vif) {
- vif->OnEvent(nullptr);
- }
- };
- uv_async_init(uvLoop_, async, asyncCb);
- async->data = vif;
- uv_async_send(async);
- uvSignals_.push_back(reinterpret_cast<uv_handle_t *>(async));
- return (uv_handle_t *)async;
- }
- uv_handle_t *VendorBase::AppendTimerEvent(int millionsecs, VendorIf *vif)
- {
- uv_timer_t *timerReq = new uv_timer_t;
- uv_timer_init(uvLoop_, timerReq);
- timerReq->data = vif;
- uv_timer_cb timerCb = [](uv_timer_t *handle) {
- VendorIf *vif = static_cast<VendorIf *>(handle->data);
- if (vif) {
- vif->OnTimer(nullptr);
- }
- };
- uv_timer_start(timerReq, timerCb, millionsecs, 1);
- uvSignals_.push_back(reinterpret_cast<uv_handle_t *>(timerReq));
- return (uv_handle_t *)(timerReq);
- }
- uv_handle_t *VendorBase::AppendTimerEvent(
- int millionsecs, std::function<void()> timerFunc)
- {
- class VendorTimerIf : public VendorIf {
- public:
- VendorTimerIf(std::function<void()> timerFunc)
- {
- timerFunc_ = timerFunc;
- }
- virtual void OnEvent(void *args) {}
- virtual void OnTimer(void *args) { timerFunc_(); }
- virtual void OnShot(void *args) {}
- private:
- std::function<void()> timerFunc_;
- };
- // 存在内存泄露问题,待更好的方案
- return AppendTimerEvent(millionsecs, new VendorTimerIf(timerFunc));
- }
- void VendorBase::StopEvent(uv_handle_t *handle)
- {
- if (handle == nullptr) {
- return;
- }
- if (handle->type == UV_TIMER) {
- uv_timer_stop((uv_timer_t *)handle);
- } else {
- uv_close(handle, nullptr);
- }
- delete handle;
- }
- void VendorBase::SignalHandler(uv_signal_t *handle, int signum)
- {
- void *l_buffer[1024];
- char **l_ptrace;
- int signal = signum;
- VendorBase *vendorBase = static_cast<VendorBase *>(handle->data);
- if (vendorBase) {
- vendorBase->Exit(signal);
- }
- HTELINK_LOG_ERR("\r\n=========>>>catch signal %d, pid: %ld <<<=========", signal, getpid());
- HTELINK_LOG_ERR("Dump stack start...");
- #ifndef WIN32
- int size = backtrace(l_buffer, 1024);
- l_ptrace = backtrace_symbols(l_buffer, size);
- if (NULL == l_ptrace) {
- HTELINK_LOG_ERR("backtrace_symbols");
- exit(signal);
- }
- 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);
- #endif
- abort();
- }
- 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
|