#include "precompile.h" #include #include #include #include #include #include #include #include #include "framework/cpp/netmsghandler.h" #include "framework/cpp/msgqueue.h" #include "framework/cpp/dbpool.h" #include "app.h" struct IMMsgNode { unsigned short msgid; a8::XParams params; IMMsgNode* next = nullptr; }; const char* const PROJ_LOG_ROOT = "/data/logs/%s/logs"; const char* const PROJ_LOG_FILENAME = "log_$pid_%Y%m%d.log"; void App::Init(int argc, char* argv[]) { this->argc = argc; this->argv = argv; if (!ParseOpt()) { terminated = true; a8::XPrintf("f8test启动失败,缺少-i参数\n", {}); return; } a8::XPrintf("f8test starting instance_id:%d pid:%d\n", {instance_id, getpid()}); signal(SIGPIPE, SIG_IGN); loop_mutex_ = new std::mutex(); loop_cond_ = new std::condition_variable(); im_msg_mutex_ = new std::mutex(); srand(time(nullptr)); InitLog(); a8::Timer::Instance()->Init(); f8::MsgQueue::Instance()->Init(); f8::DBPool::Instance()->Init(); f8::DBPool::Instance()->SetThreadNum(10); a8::UdpLog::Instance()->Info("f8test starting instance_id:%d pid:%d", {instance_id, getpid()}); } void App::UnInit() { if (terminated) { return; } f8::DBPool::Instance()->UnInit(); f8::MsgQueue::Instance()->UnInit(); a8::Timer::Instance()->UnInit(); UnInitLog(); delete im_msg_mutex_; im_msg_mutex_ = nullptr; delete loop_cond_; loop_cond_ = nullptr; delete loop_mutex_; loop_mutex_ = nullptr; } int App::Run() { if (terminated) { return 0; } int ret = 0; a8::UdpLog::Instance()->Info("f8test running", {}); while (!terminated) { #if 0 a8::tick_t begin_tick = a8::XGetTickCount(); #endif QuickExecute(); SlowerExecute(); #if 0 a8::tick_t end_tick = a8::XGetTickCount(); #endif Schedule(); } return ret; } void App::AddIMMsg(unsigned short imcmd, a8::XParams params) { IMMsgNode *p = new IMMsgNode; p->msgid = imcmd; p->params = params; p->next = nullptr; im_msg_mutex_->lock(); if (im_bot_node_) { im_bot_node_->next = p; im_bot_node_ = p; } else { im_top_node_ = p; im_bot_node_ = p; } im_msg_mutex_->unlock(); NotifyLoopCond(); } void App::QuickExecute() { ProcessIMMsg(); a8::Timer::Instance()->Update(); } void App::SlowerExecute() { } void App::NotifyLoopCond() { std::unique_lock lk(*loop_mutex_); loop_cond_->notify_all(); } void App::Schedule() { std::unique_lock lk(*loop_mutex_); if (!HasTask()) { int sleep_time = a8::Timer::Instance()->GetIdleableMillSeconds(); loop_cond_->wait_for(lk, std::chrono::milliseconds(sleep_time)); } } bool App::HasTask() { { if (!im_work_node_) { im_msg_mutex_->lock(); if (!im_work_node_ && im_top_node_) { im_work_node_ = im_top_node_; im_top_node_ = nullptr; im_bot_node_ = nullptr; } im_msg_mutex_->unlock(); } if (im_work_node_) { return true; } } return false; } void App::ProcessIMMsg() { if (!im_work_node_ && im_top_node_) { im_msg_mutex_->lock(); im_work_node_ = im_top_node_; im_top_node_ = nullptr; im_bot_node_ = nullptr; im_msg_mutex_->unlock(); } while (im_work_node_) { IMMsgNode *pdelnode = im_work_node_; switch (im_work_node_->msgid) { case f8::IM_SysMsgQueue: { const a8::XParams* param = (const a8::XParams*)pdelnode->params.param1.GetUserData(); f8::MsgQueue::Instance()->ProcessMsg(pdelnode->params.sender.GetInt(), *param ); delete param; } break; } im_work_node_ = im_work_node_->next; delete pdelnode; } } void App::InitLog() { std::string filename_fmt = PROJ_LOG_FILENAME; if (getenv("is_dev_env")) { a8::ReplaceString(filename_fmt, "$pid", a8::XValue(0)); } else { a8::ReplaceString(filename_fmt, "$pid", a8::XValue(getpid())); } a8::MkDir(a8::Format(PROJ_ROOT, {PROJ_NAME})); a8::MkDir(a8::Format(PROJ_LOG_ROOT, {PROJ_NAME})); a8::UdpLog::Instance()->SetLogFileName(a8::Format(PROJ_LOG_ROOT, {PROJ_NAME}) + "/" + filename_fmt); a8::UdpLog::Instance()->Init(); } void App::UnInitLog() { a8::UdpLog::Instance()->UnInit(); } bool App::ParseOpt() { int ch = 0; while ((ch = getopt(argc, argv, "i:")) != -1) { switch (ch) { case 'i': { instance_id = a8::XValue(optarg); } break; } } return instance_id > 0; } a8::XParams* App::AddContext(long long context_id) { context_hash_[context_id] = a8::XParams(); return GetContext(context_id); } void App::DelContext(long long context_id) { context_hash_.erase(context_id); } a8::XParams* App::GetContext(long long context_id) { auto itr = context_hash_.find(context_id); return itr != context_hash_.end() ? &(itr->second) : nullptr; }