diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2f6d494 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.h linguist-language=C++ diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 76d401e..0000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: CMake - -on: - push: - branches: [ master, dev ] - pull_request: - branches: [ master ] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - Ubuntu-latest: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - run: sudo apt update - - run: sudo apt install build-essential cmake git - - run: sudo apt install libjsoncpp-dev libgflags-dev libgtest-dev libgoogle-glog-dev libunwind-dev - - name: Check code style - run: bash ${{github.workspace}}/cpplint.bash - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - - name: Install - run: cd ${{github.workspace}}/build && sudo make install - - Ubuntu2004: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v2 - - run: sudo apt update - - run: sudo apt install build-essential cmake git - - run: sudo apt install libjsoncpp-dev libgflags-dev libgtest-dev libgoogle-glog-dev - - name: Check code style - run: bash ${{github.workspace}}/cpplint.bash - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - - name: Install - run: cd ${{github.workspace}}/build && sudo make install - - Ubuntu2204: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v2 - - run: sudo apt update - - run: sudo apt install build-essential cmake git - - run: sudo apt install libjsoncpp-dev libgflags-dev libgtest-dev libgoogle-glog-dev libunwind-dev - - name: Check code style - run: bash ${{github.workspace}}/cpplint.bash - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - - name: Install - run: cd ${{github.workspace}}/build && sudo make install diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml new file mode 100644 index 0000000..8fcea64 --- /dev/null +++ b/.github/workflows/codestyle.yml @@ -0,0 +1,13 @@ +name: codestyle + +on: [push, pull_request] + +jobs: + Ubuntu-latest: + name: codestyle + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Check code style + run: bash ${{github.workspace}}/cpplint.bash \ No newline at end of file diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000..e81d035 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,50 @@ +name: Linux + +on: [push, pull_request] + +jobs: + Ubuntu-latest: + name: GCC-C++${{matrix.std}}-${{matrix.build_type}} + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + build_type: [Release, Debug] + std: [17, 20] + + steps: + - uses: actions/checkout@v3 + - run: sudo apt update + - run: sudo apt install build-essential cmake ninja-build + - run: sudo apt install libjsoncpp-dev libgflags-dev libgtest-dev libgoogle-glog-dev libunwind-dev + + - name: Setup Ninja + uses: ashutoshvarma/setup-ninja@master + with: + version: 1.10.0 + + - name: Configure CMake + env: + # glog option: + # -DNDEBUG + # -DDCHECK_ALWAYS_ON + # unit test option: + # -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined + CXXFLAGS: ${{env.CXXFLAGS}} -DNDEBUG -fPIC -Wall -Wextra -Werror -pedantic-errors -Wswitch-default -Wfloat-equal -Wshadow -Wcast-qual -Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wsign-promo -Wsuggest-override + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: | + cmake -S . -B ${{github.workspace}}/build_${{matrix.build_type}} \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install \ + -G Ninja \ + -Werror + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build_${{matrix.build_type}} --config ${{matrix.build_type}} diff --git a/3rd/README.md b/3rd/README.md deleted file mode 100644 index 3a748ae..0000000 --- a/3rd/README.md +++ /dev/null @@ -1 +0,0 @@ -# 第三方的开源库 diff --git a/CMakeLists.txt b/CMakeLists.txt index dfb70de..28f48d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,25 +12,6 @@ if (CMAKE_COMPILER_IS_GNUCC) endif () ### cpp option -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED YES) -# glog option: -# -DNDEBUG -# -DDCHECK_ALWAYS_ON -# unit test option: -# -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -set(CMAKE_C_FLAGS - "-fPIC -Wall -Wextra -Werror -pedantic-errors \ - -Wswitch-default -Wfloat-equal -Wshadow -Wcast-qual \ - -DNDEBUG" -) -set(CMAKE_CXX_FLAGS - "-fPIC -Wall -Wextra -Werror -pedantic-errors \ - -Wswitch-default -Wfloat-equal -Wshadow -Wcast-qual \ - -Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wsign-promo -Wsuggest-override \ - -DNDEBUG" -) if (GCC_VERSION GREATER "8.0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra-semi") endif () @@ -46,11 +27,11 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MYFRAME_OUTPUT_ROOT}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MYFRAME_OUTPUT_ROOT}/bin) ### install path -set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/${CMAKE_PROJECT_NAME}") +# set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/${CMAKE_PROJECT_NAME}") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") set(MYFRAME_TEST_DIR "test") set(MYFRAME_BIN_DIR "bin") -set(MYFRAME_INC_DIR "inc") +set(MYFRAME_INC_DIR "include") set(MYFRAME_LIB_DIR "lib") set(MYFRAME_LOG_DIR "log") set(MYFRAME_SERVICE_DIR "service") @@ -89,10 +70,7 @@ endif() ### install file/dir install(FILES "LICENSE" - PERMISSIONS - OWNER_READ - GROUP_READ - WORLD_READ + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ DESTINATION . ) install(DIRECTORY templates DESTINATION .) @@ -112,8 +90,14 @@ execute_process( OUTPUT_VARIABLE GIT_COMMIT_ID OUTPUT_STRIP_TRAILING_WHITESPACE ) +execute_process( + COMMAND git show -s --format=%ci HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE +) install(CODE " file( WRITE ${CMAKE_INSTALL_PREFIX}/version.txt - \"${GIT_BRANCH}\n${GIT_COMMIT_ID}\n\") + \"${GIT_BRANCH}\n${GIT_COMMIT_ID}\n${GIT_COMMIT_DATE}\n\") ") diff --git a/README.md b/README.md index 9b678d4..27a6540 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,19 @@ ![myframe](doc/pics/myframe.png) ## 概述 -C++实现的actors框架,程序由actor和worker组成; +C++实现的组件化的编程框架,程序由actor和worker组成; actor基于消息驱动,actor之间可以进行消息传递; worker自驱动,可以通过消息与actor交互; -组件化的编程模式可以提高代码复用,降低程序耦合度。 +适用于构建中大型项目. ## 开发/运行环境 操作系统: Ubuntu 18.04+ 开发语言:C++17 -## 安装依赖 -参考 [github ci](.github/workflows/cmake.yml) - ## 构建 -```sh -mkdir build -cd build -cmake .. -# 默认安装到HOME目录 -make -j4 install -``` +参考 [github ci](.github/workflows/linux.yml) -## 运行 +## 运行所有的example ```sh cd ~/myframe/bin ./launcher -p app @@ -102,4 +93,3 @@ extern "C" std::shared_ptr actor_create(const std::string& actor_name) { - [Discussions](https://github.com/lkpworkspace/myframe/discussions) - [WIKI](https://github.com/lkpworkspace/myframe/wiki) - [FAQ](https://github.com/lkpworkspace/myframe/wiki/FAQs) -- [TODOLIST](doc/TODOLIST.md) diff --git a/cpplint.bash b/cpplint.bash index 9e393f2..4f3c610 100755 --- a/cpplint.bash +++ b/cpplint.bash @@ -5,7 +5,7 @@ function main() { set -e cd "$PWD0" # shellcheck disable=SC2038 - find '(' \ + find . '(' \ -name "*.c" -or \ -name "*.cc" -or \ -name "*.h" -or \ @@ -18,7 +18,7 @@ function main() { -name "*.hxx" -or \ -name "*.cxx" -or \ -name "*.cuh" \ - ')' | xargs ./cpplint.py + ')' | xargs python3 ./cpplint.py } main "$@" diff --git a/doc/TODOLIST.md b/doc/TODOLIST.md deleted file mode 100644 index 6ecf57b..0000000 --- a/doc/TODOLIST.md +++ /dev/null @@ -1 +0,0 @@ -# TODOLIST diff --git a/doc/development_guide.md b/doc/development_guide.md index b7eeebf..bd3a5d3 100644 --- a/doc/development_guide.md +++ b/doc/development_guide.md @@ -62,5 +62,20 @@ python3 ~/myframe/tools/gen_mod_proj.py --dir="/path/to/proj_dir/" --name="mod_n - 配置文件: - Template.json:Service配置 -### 安装 -通过make install安装到框架中的组件目录中 +### 组件工程构建安装 +```sh +cmake -S . -B build -DCMAKE_INSTALL_PREFIX=${myframe目录} +make -C build -j "$(nproc)" install +``` + +### 运行组件 +```sh +cd ${myframe目录}/bin +./launcher -c ${组件名}.json -p app +``` + +### 查看运行日志 +```sh +cd ${myframe目录}/log +vi ${日志} +``` diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 67ac9ee..02af264 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,39 +2,36 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.10) ### actor add_library(example_actor_helloworld SHARED example_actor_helloworld.cpp) -target_link_libraries(example_actor_helloworld myframe) +target_link_libraries(example_actor_helloworld ${PROJECT_NAME}) add_library(example_actor_timer SHARED example_actor_timer.cpp) -target_link_libraries(example_actor_timer myframe) +target_link_libraries(example_actor_timer ${PROJECT_NAME}) add_library(example_actor_serial SHARED example_actor_serial.cpp) -target_link_libraries(example_actor_serial myframe) +target_link_libraries(example_actor_serial ${PROJECT_NAME}) add_library(example_actor_concurrent SHARED example_actor_concurrent.cpp) -target_link_libraries(example_actor_concurrent myframe) +target_link_libraries(example_actor_concurrent ${PROJECT_NAME}) ### worker add_library(example_worker_publish SHARED example_worker_publish.cpp) -target_link_libraries(example_worker_publish myframe) +target_link_libraries(example_worker_publish ${PROJECT_NAME}) add_library(example_worker_talk SHARED example_worker_talk.cpp) -target_link_libraries(example_worker_talk myframe) +target_link_libraries(example_worker_talk ${PROJECT_NAME}) add_library(example_worker_actor_interactive SHARED example_worker_actor_interactive.cpp) -target_link_libraries(example_worker_actor_interactive myframe) +target_link_libraries(example_worker_actor_interactive ${PROJECT_NAME}) add_library(example_worker_interactive_with_3rd_frame SHARED example_worker_interactive_with_3rd_frame.cpp) -target_link_libraries(example_worker_interactive_with_3rd_frame myframe) +target_link_libraries(example_worker_interactive_with_3rd_frame ${PROJECT_NAME}) add_library(example_worker_quit SHARED example_worker_quit.cpp) -target_link_libraries(example_worker_quit myframe) +target_link_libraries(example_worker_quit ${PROJECT_NAME}) add_library(example_config SHARED example_config.cpp) -target_link_libraries(example_config myframe) +target_link_libraries(example_config ${PROJECT_NAME}) add_library(example_trans_obj SHARED example_trans_obj.cpp) -target_link_libraries(example_trans_obj myframe) +target_link_libraries(example_trans_obj ${PROJECT_NAME}) ### install FILE(GLOB conf_files "*.json") INSTALL(FILES ${conf_files} - PERMISSIONS - OWNER_READ - GROUP_READ - WORLD_READ + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ DESTINATION ${MYFRAME_SERVICE_DIR} ) INSTALL(TARGETS diff --git a/examples/example_worker_interactive_with_3rd_frame.cpp b/examples/example_worker_interactive_with_3rd_frame.cpp index 87925b3..ef00211 100644 --- a/examples/example_worker_interactive_with_3rd_frame.cpp +++ b/examples/example_worker_interactive_with_3rd_frame.cpp @@ -24,23 +24,23 @@ class MyQueue final { MyQueue() = default; ~MyQueue() = default; - int GetFd0() { return cmd_channel_.GetOwnerFd(); } - int GetFd1() { return cmd_channel_.GetMainFd(); } + int GetFd0() { return cmd_channel_.GetOwnerHandle(); } + int GetFd1() { return cmd_channel_.GetMainHandle(); } void Push(std::shared_ptr data) { data_ = data; - myframe::Cmd cmd = myframe::Cmd::kRun; + myframe::CmdChannel::Cmd cmd = myframe::CmdChannel::Cmd::kRun; cmd_channel_.SendToOwner(cmd); cmd_channel_.RecvFromOwner(&cmd); } std::shared_ptr Pop() { std::shared_ptr ret = nullptr; - myframe::Cmd cmd = myframe::Cmd::kRun; + myframe::CmdChannel::Cmd cmd = myframe::CmdChannel::Cmd::kRun; cmd_channel_.RecvFromMain(&cmd); ret = data_; data_ = nullptr; - cmd_channel_.SendToMain(myframe::Cmd::kIdle); + cmd_channel_.SendToMain(myframe::CmdChannel::Cmd::kIdle); return ret; } @@ -70,13 +70,13 @@ class ExampleWorkerInteractiveWith3rdFrame : public myframe::Worker { }); // 通知myframe该worker可以接收来自myframe的消息 - GetCmdChannel()->SendToMain(myframe::Cmd::kWaitForMsg); + GetCmdChannel()->SendToMain(myframe::CmdChannel::Cmd::kWaitForMsg); } void Run() override { auto cmd_channel = GetCmdChannel(); struct pollfd fds[] = { - {cmd_channel->GetOwnerFd(), POLLIN, 0}, + {cmd_channel->GetOwnerHandle(), POLLIN, 0}, {queue_.GetFd0(), POLLIN, 0}}; // 等待来自queue或者myframe的消息 int ret = poll(fds, 2, -1); @@ -89,15 +89,40 @@ class ExampleWorkerInteractiveWith3rdFrame : public myframe::Worker { continue; } if (i == 0) { - OnMainMsg(); + myframe::CmdChannel::Cmd cmd; + cmd_channel->RecvFromMain(&cmd); + if (cmd == myframe::CmdChannel::Cmd::kRun) { + recv_run_flag_ = true; + } else if (cmd == myframe::CmdChannel::Cmd::kRunWithMsg) { + auto mailbox = GetMailbox(); + while (!mailbox->RecvEmpty()) { + const auto& msg = mailbox->PopRecv(); + // 接收到其它组件消息 + LOG(INFO) << "get main " << msg->GetData(); + } + cmd_channel->SendToMain(myframe::CmdChannel::Cmd::kWaitForMsg); + } else if (cmd == myframe::CmdChannel::Cmd::kQuit) { + quit_.store(true); + Stop(); + } } else if (i == 1) { auto data = queue_.Pop(); - // 可以将queue里的消息发给myfrmae的worker或actor - // eg: Send("actor.xx.xx", std::make_shared(data->c_str())); - LOG(INFO) << "get 3rd frame: " << data->c_str(); - cmd_channel->SendToMain(myframe::Cmd::kIdle); + // 接收到来自外部的消息 + LOG(INFO) << "get 3rd frame: " << *data; + send_msgs_.push_back(std::make_shared(data->c_str())); } } + // 分发外部消息给程序的其它组件 + if (recv_run_flag_ && !send_msgs_.empty()) { + recv_run_flag_ = false; + LOG(INFO) << "pub 3rd msg to main " << send_msgs_.size(); + // auto mailbox = GetMailbox(); + for (std::size_t i = 0; i < send_msgs_.size(); ++i) { + // mailbox->Send("actor.xx.xx", send_msgs_[i]); + } + send_msgs_.clear(); + cmd_channel->SendToMain(myframe::CmdChannel::Cmd::kIdle); + } } void Exit() override { @@ -106,33 +131,9 @@ class ExampleWorkerInteractiveWith3rdFrame : public myframe::Worker { } } - // 分发消息、处理来自myframe的消息 - void OnMainMsg() { - auto cmd_channel = GetCmdChannel(); - myframe::Cmd cmd; - cmd_channel->RecvFromMain(&cmd); - if (cmd == myframe::Cmd::kRun) { - // do nothing - return; - } else if (cmd == myframe::Cmd::kRunWithMsg) { - ProcessMainMsg(); - cmd_channel->SendToMain(myframe::Cmd::kWaitForMsg); - } else if (cmd == myframe::Cmd::kQuit) { - quit_.store(true); - Stop(); - } - } - - void ProcessMainMsg() { - auto mailbox = GetMailbox(); - while (!mailbox->RecvEmpty()) { - const auto& msg = mailbox->PopRecv(); - // ... - LOG(INFO) << "get main " << msg->GetData(); - } - } - private: + bool recv_run_flag_{true}; + std::vector> send_msgs_; int seq_num_{0}; std::atomic_bool quit_{true}; std::thread th_; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 9636aef..3a61699 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -4,16 +4,15 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.10) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/launcher_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/launcher_config.h @ONLY) ### source -get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME_WE) -project(${PROJECT_NAME}) +get_filename_component(DIR_NAME ${CMAKE_CURRENT_LIST_DIR} NAME_WE) aux_source_directory(. __srcs) ### bin -add_executable(${PROJECT_NAME} ${__srcs}) -target_link_libraries(${PROJECT_NAME} myframe) +add_executable(${DIR_NAME} ${__srcs}) +target_link_libraries(${DIR_NAME} ${PROJECT_NAME}) ### install -install(TARGETS ${PROJECT_NAME} +install(TARGETS ${DIR_NAME} LIBRARY DESTINATION ${MYFRAME_LIB_DIR} ARCHIVE DESTINATION ${MYFRAME_LIB_DIR} RUNTIME DESTINATION ${MYFRAME_BIN_DIR} diff --git a/launcher/launcher.cpp b/launcher/launcher.cpp index d07f3f9..3293dc9 100644 --- a/launcher/launcher.cpp +++ b/launcher/launcher.cpp @@ -74,7 +74,8 @@ int main(int argc, char** argv) { } if (!g_app->LoadServiceFromFile(abs_conf_file)) { LOG(ERROR) << "Load " << abs_conf_file << " failed, exit"; - return -1; + g_app->Quit(); + break; } } } else { @@ -90,7 +91,7 @@ int main(int argc, char** argv) { } if (g_app->LoadServiceFromDir(abs_service_dir) <= 0) { LOG(ERROR) << "Load service from " << abs_service_dir << " failed, exit"; - return -1; + g_app->Quit(); } } diff --git a/myframe/CMakeLists.txt b/myframe/CMakeLists.txt index e24ff3f..aecfc05 100644 --- a/myframe/CMakeLists.txt +++ b/myframe/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.10) ### source -get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME_WE) -project(${PROJECT_NAME}) aux_source_directory(. __srcs) ### lib @@ -19,17 +17,13 @@ file(GLOB header_files actor.h event.h worker.h - mod_lib.h mod_manager.h app.h ) install(FILES ${header_files} - PERMISSIONS - OWNER_READ - GROUP_READ - WORLD_READ - DESTINATION ${MYFRAME_INC_DIR}/myframe + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + DESTINATION ${MYFRAME_INC_DIR}/${PROJECT_NAME} ) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${MYFRAME_LIB_DIR} diff --git a/myframe/actor_context_manager.cpp b/myframe/actor_context_manager.cpp index ac710cf..dc8fcf4 100644 --- a/myframe/actor_context_manager.cpp +++ b/myframe/actor_context_manager.cpp @@ -22,12 +22,10 @@ namespace myframe { ActorContextManager::ActorContextManager() : ctx_count_(0) { LOG(INFO) << "ActorContextManager create"; - pthread_rwlock_init(&rw_, NULL); } ActorContextManager::~ActorContextManager() { LOG(INFO) << "ActorContextManager deconstruct"; - pthread_rwlock_destroy(&rw_); } void ActorContextManager::DispatchMsg(std::shared_ptr msg) { @@ -42,47 +40,41 @@ void ActorContextManager::DispatchMsg(std::shared_ptr msg) { } bool ActorContextManager::RegContext(std::shared_ptr ctx) { - pthread_rwlock_wrlock(&rw_); + std::unique_lock lk(rw_); if (ctxs_.find(ctx->GetActor()->GetActorName()) != ctxs_.end()) { LOG(WARNING) << "reg the same actor name: " << ctx->GetActor()->GetActorName(); - pthread_rwlock_unlock(&rw_); return false; } LOG(INFO) << "reg actor " << ctx->GetActor()->GetActorName(); ctxs_[ctx->GetActor()->GetActorName()] = ctx; - pthread_rwlock_unlock(&rw_); return true; } std::shared_ptr ActorContextManager::GetContext( const std::string& actor_name) { - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); if (ctxs_.find(actor_name) == ctxs_.end()) { LOG(WARNING) << "not found " << actor_name; - pthread_rwlock_unlock(&rw_); return nullptr; } auto ctx = ctxs_[actor_name]; - pthread_rwlock_unlock(&rw_); return ctx; } std::vector ActorContextManager::GetAllActorAddr() { std::vector res; - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); for (auto ctx : ctxs_) { res.push_back(ctx.first); } - pthread_rwlock_unlock(&rw_); return res; } bool ActorContextManager::HasActor(const std::string& name) { bool res = false; - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); res = (ctxs_.find(name) != ctxs_.end()); - pthread_rwlock_unlock(&rw_); return res; } diff --git a/myframe/actor_context_manager.h b/myframe/actor_context_manager.h index 264a83c..174cfae 100644 --- a/myframe/actor_context_manager.h +++ b/myframe/actor_context_manager.h @@ -6,9 +6,10 @@ Author: likepeng ****************************************************************************/ #pragma once -#include #include +#include +#include #include #include #include @@ -48,7 +49,7 @@ class ActorContextManager final { /// 待处理actor链表 std::list> wait_queue_; /// 读写锁 - pthread_rwlock_t rw_; + std::shared_mutex rw_; /// key: context name, value: context std::unordered_map> ctxs_; diff --git a/myframe/app.cpp b/myframe/app.cpp index 19ea4c2..c732a74 100644 --- a/myframe/app.cpp +++ b/myframe/app.cpp @@ -7,12 +7,6 @@ Author: likepeng #include "myframe/app.h" -#include -#include -#include - -#include - #include #include "myframe/common.h" @@ -21,6 +15,7 @@ Author: likepeng #include "myframe/actor.h" #include "myframe/actor_context.h" #include "myframe/actor_context_manager.h" +#include "myframe/event_manager.h" #include "myframe/event_conn.h" #include "myframe/event_conn_manager.h" #include "myframe/worker_context.h" @@ -28,6 +23,7 @@ Author: likepeng #include "myframe/worker_timer.h" #include "myframe/worker_context_manager.h" #include "myframe/mod_manager.h" +#include "myframe/poller.h" namespace myframe { @@ -37,7 +33,7 @@ std::shared_ptr App::GetTimerWorker() { return nullptr; } std::string worker_timer_name = "worker.timer.#1"; - auto w = worker_ctx_mgr_->Get(worker_timer_name); + auto w = ev_mgr_->Get(worker_timer_name); if (w == nullptr) { LOG(ERROR) << "can't find " << worker_timer_name; @@ -48,18 +44,15 @@ std::shared_ptr App::GetTimerWorker() { } App::App() - : epoll_fd_(-1) + : poller_(new Poller()) , mods_(new ModManager()) , actor_ctx_mgr_(new ActorContextManager()) - , ev_conn_mgr_(new EventConnManager()) - , worker_ctx_mgr_(new WorkerContextManager()) + , ev_mgr_(new EventManager()) + , ev_conn_mgr_(new EventConnManager(ev_mgr_)) + , worker_ctx_mgr_(new WorkerContextManager(ev_mgr_)) {} App::~App() { - if (epoll_fd_ != -1) { - close(epoll_fd_); - epoll_fd_ = -1; - } LOG(INFO) << "app deconstruct"; } @@ -71,18 +64,13 @@ bool App::Init( if (!quit_.load()) { return true; } - epoll_fd_ = epoll_create(1024); - if (-1 == epoll_fd_) { - LOG(ERROR) << strerror(errno); - return false; - } - LOG(INFO) << "Create epoll fd " << epoll_fd_; bool ret = true; lib_dir_ = lib_dir; warning_msg_size_.store(warning_msg_size); + ret &= poller_->Init(); ret &= worker_ctx_mgr_->Init(warning_msg_size); - ret &= ev_conn_mgr_->Init(shared_from_this(), event_conn_size); + ret &= ev_conn_mgr_->Init(event_conn_size); ret &= StartCommonWorker(thread_pool_size); ret &= StartTimerWorker(); @@ -302,7 +290,7 @@ bool App::AddWorker( if (!worker_ctx_mgr_->Add(worker_ctx)) { return false; } - if (!AddEvent(worker_ctx)) { + if (!poller_->Add(worker_ctx)) { return false; } worker_ctx->Start(); @@ -312,8 +300,14 @@ bool App::AddWorker( int App::Send( const std::string& dst, std::shared_ptr msg) { - auto conn = ev_conn_mgr_->Get(); + auto conn = ev_conn_mgr_->Alloc(); + if (conn == nullptr) { + LOG(ERROR) << "alloc conn event failed"; + return -1; + } + poller_->Add(conn); auto ret = conn->Send(dst, msg); + poller_->Del(conn); ev_conn_mgr_->Release(conn); return ret; } @@ -321,8 +315,14 @@ int App::Send( const std::shared_ptr App::SendRequest( const std::string& name, std::shared_ptr msg) { - auto conn = ev_conn_mgr_->Get(); + auto conn = ev_conn_mgr_->Alloc(); + if (conn == nullptr) { + LOG(ERROR) << "alloc conn event failed"; + return nullptr; + } + poller_->Add(conn); auto resp = conn->SendRequest(name, msg); + poller_->Del(conn); ev_conn_mgr_->Release(conn); return resp; } @@ -365,37 +365,6 @@ bool App::CreateActorContext( return true; } -bool App::AddEvent(std::shared_ptr ev) { - struct epoll_event event; - event.data.fd = ev->GetFd(); - event.events = ToEpollType(ev->ListenIOType()); - int res = 0; - // 如果该事件已经注册,就修改事件类型 - res = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, ev->GetFd(), &event); - if (-1 == res) { - // 没有注册就添加至epoll - res = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, ev->GetFd(), &event); - if (-1 == res) { - LOG(ERROR) << "epoll " << strerror(errno); - return false; - } - } else { - LOG(WARNING) - << " has already reg ev " << ev->GetFd() << ": " - << strerror(errno); - return false; - } - return true; -} - -bool App::DelEvent(std::shared_ptr ev) { - if (-1 == epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, ev->GetFd(), NULL)) { - LOG(ERROR) << "del event " << ev->GetFd() << ": " << strerror(errno); - return false; - } - return true; -} - bool App::StartCommonWorker(int worker_count) { bool ret = false; for (int i = 0; i < worker_count; ++i) { @@ -424,28 +393,6 @@ bool App::StartTimerWorker() { return true; } -EventIOType App::ToEventIOType(int ev) { - switch (ev) { - case EPOLLIN: - return EventIOType::kIn; - case EPOLLOUT: - return EventIOType::kOut; - default: - return EventIOType::kNone; - } -} - -int App::ToEpollType(const EventIOType& type) { - switch (type) { - case EventIOType::kIn: - return EPOLLIN; - case EventIOType::kOut: - return EPOLLOUT; - default: - return EPOLLERR; - } -} - void App::DispatchMsg(std::list>* msg_list) { LOG_IF(WARNING, msg_list->size() > warning_msg_size_.load()) @@ -479,7 +426,7 @@ void App::DispatchMsg(std::list>* msg_list) { continue; } if (name_list[0] == "worker" - && worker_ctx_mgr_->HasWorker(msg->GetDst())) { + && ev_mgr_->Has(msg->GetDst())) { // dispatch to user worker worker_ctx_mgr_->DispatchWorkerMsg(msg); } else if (name_list[0] == "actor" @@ -488,7 +435,8 @@ void App::DispatchMsg(std::list>* msg_list) { actor_ctx_mgr_->DispatchMsg(msg); } else if (name_list[0] == "event") { if (name_list[1] == "conn") { - ev_conn_mgr_->Notify(msg->GetDst(), msg); + auto handle = ev_mgr_->ToHandle(msg->GetDst()); + ev_conn_mgr_->Notify(handle, msg); } else { LOG(ERROR) << "Unknown msg " << *msg; } @@ -547,7 +495,7 @@ void App::CheckStopWorkers() { worker_ctx_mgr_->PopFrontIdleWorker(); auto common_idle_worker = worker_ctx->GetWorker(); common_idle_worker->SetActorContext(actor_ctx); - worker_ctx->GetCmdChannel()->SendToOwner(Cmd::kRun); + worker_ctx->GetCmdChannel()->SendToOwner(CmdChannel::Cmd::kRun); } else { LOG(ERROR) << actor_ctx->GetActor()->GetActorName() << " has no msg"; } @@ -602,18 +550,18 @@ void App::ProcessTimerEvent(std::shared_ptr worker_ctx) { DLOG(INFO) << *worker_ctx << " dispatch msg..."; DispatchMsg(worker_ctx->GetMailbox()->GetSendList()); - Cmd cmd; + CmdChannel::Cmd cmd; auto cmd_channel = worker_ctx->GetCmdChannel(); cmd_channel->RecvFromOwner(&cmd); switch (cmd) { - case Cmd::kIdle: // idle + case CmdChannel::Cmd::kIdle: // idle DLOG(INFO) << *worker_ctx << " run again"; - cmd_channel->SendToOwner(Cmd::kRun); + cmd_channel->SendToOwner(CmdChannel::Cmd::kRun); break; - case Cmd::kQuit: // quit + case CmdChannel::Cmd::kQuit: // quit LOG(INFO) << *worker_ctx << " quit, delete from main"; - DelEvent(worker_ctx); + poller_->Del(worker_ctx); worker_ctx_mgr_->Del(worker_ctx); break; default: @@ -627,21 +575,21 @@ void App::ProcessUserEvent(std::shared_ptr worker_ctx) { DLOG(INFO) << *worker_ctx << " dispatch msg..."; DispatchMsg(worker_ctx->GetMailbox()->GetSendList()); - Cmd cmd; + CmdChannel::Cmd cmd; auto cmd_channel = worker_ctx->GetCmdChannel(); cmd_channel->RecvFromOwner(&cmd); switch (cmd) { - case Cmd::kIdle: // idle + case CmdChannel::Cmd::kIdle: // idle DLOG(INFO) << *worker_ctx << " run again"; - cmd_channel->SendToOwner(Cmd::kRun); + cmd_channel->SendToOwner(CmdChannel::Cmd::kRun); break; - case Cmd::kWaitForMsg: + case CmdChannel::Cmd::kWaitForMsg: DLOG(INFO) << *worker_ctx << " wait for msg..."; worker_ctx_mgr_->PushWaitWorker(worker_ctx); break; - case Cmd::kQuit: // quit + case CmdChannel::Cmd::kQuit: // quit LOG(INFO) << *worker_ctx << " quit, delete from main"; - DelEvent(worker_ctx); + poller_->Del(worker_ctx); worker_ctx_mgr_->Del(worker_ctx); break; default: @@ -657,15 +605,13 @@ void App::ProcessWorkerEvent(std::shared_ptr worker_ctx) { DLOG_IF(INFO, worker->GetActorContext() != nullptr) << *worker_ctx << " dispatch " << worker->GetActorContext()->GetActor()->GetActorName() << " msg..."; - LOG_IF(WARNING, worker->GetActorContext() == nullptr) - << *worker_ctx << " no context"; DispatchMsg(worker->GetActorContext()); - Cmd cmd; + CmdChannel::Cmd cmd; auto cmd_channel = worker->GetCmdChannel(); cmd_channel->RecvFromOwner(&cmd); switch (cmd) { - case Cmd::kIdle: // idle + case CmdChannel::Cmd::kIdle: // idle // 将工作线程中的actor状态设置为全局状态 // 将线程加入空闲队列 DLOG(INFO) @@ -674,11 +620,11 @@ void App::ProcessWorkerEvent(std::shared_ptr worker_ctx) { worker->Idle(); worker_ctx_mgr_->PushBackIdleWorker(worker_ctx); break; - case Cmd::kQuit: // quit + case CmdChannel::Cmd::kQuit: // quit LOG(INFO) << *worker_ctx << " quit, delete from main"; - DelEvent(worker_ctx); + poller_->Del(worker_ctx); worker_ctx_mgr_->Del(worker_ctx); // FIXME: 应该将worker加入删除队列,等worker运行结束后再从队列删除 // 否则会造成删除智能指针后,worker还没结束运行造成coredump @@ -693,13 +639,13 @@ void App::ProcessEventConn(std::shared_ptr ev) { // 将event_conn的发送队列分发完毕 DispatchMsg(ev->GetMailbox()->GetSendList()); auto cmd_channel = ev->GetCmdChannel(); - Cmd cmd; + CmdChannel::Cmd cmd; cmd_channel->RecvFromOwner(&cmd); switch (cmd) { - case Cmd::kRun: - cmd_channel->SendToOwner(Cmd::kIdle); + case CmdChannel::Cmd::kRun: + cmd_channel->SendToOwner(CmdChannel::Cmd::kIdle); break; - case Cmd::kRunWithMsg: + case CmdChannel::Cmd::kRunWithMsg: // do nothing break; default: @@ -708,30 +654,25 @@ void App::ProcessEventConn(std::shared_ptr ev) { } } -void App::ProcessEvent(struct epoll_event* evs, int ev_count) { - DLOG_IF(INFO, ev_count > 0) << "get " << ev_count << " event"; - for (int i = 0; i < ev_count; ++i) { - std::shared_ptr ev_obj = nullptr; - ev_obj = worker_ctx_mgr_->Get(evs[i].data.fd); +void App::ProcessEvent(const std::vector& evs) { + DLOG_IF(INFO, evs.size() > 0) << "get " << evs.size() << " event"; + for (size_t i = 0; i < evs.size(); ++i) { + auto ev_obj = ev_mgr_->Get(evs[i]); if (ev_obj == nullptr) { - ev_obj = ev_conn_mgr_->Get(evs[i].data.fd); - if (ev_obj == nullptr) { - LOG(ERROR) << "can't find ev obj, handle " << evs[i].data.fd; - continue; - } + LOG(ERROR) << "can't find ev obj, handle " << evs[i]; + continue; } - ev_obj->RetListenIOType(ToEventIOType(evs[i].events)); switch (ev_obj->GetType()) { - case EventType::kWorkerCommon: + case Event::Type::kWorkerCommon: ProcessWorkerEvent(std::dynamic_pointer_cast(ev_obj)); break; - case EventType::kWorkerTimer: + case Event::Type::kWorkerTimer: ProcessTimerEvent(std::dynamic_pointer_cast(ev_obj)); break; - case EventType::kWorkerUser: + case Event::Type::kWorkerUser: ProcessUserEvent(std::dynamic_pointer_cast(ev_obj)); break; - case EventType::kEventConn: + case Event::Type::kEventConn: ProcessEventConn(std::dynamic_pointer_cast(ev_obj)); break; default: @@ -742,31 +683,20 @@ void App::ProcessEvent(struct epoll_event* evs, int ev_count) { } int App::Exec() { - int ev_count = 0; - int max_ev_count = 64; int time_wait_ms = 1000; - struct epoll_event* evs = nullptr; - auto void_evs = malloc(sizeof(struct epoll_event) * max_ev_count); - evs = reinterpret_cast(void_evs); + std::vector evs; while (worker_ctx_mgr_->WorkerSize()) { /// 检查空闲线程队列是否有空闲线程,如果有就找到一个有消息的actor处理 CheckStopWorkers(); /// 等待事件 - ev_count = epoll_wait(epoll_fd_, evs, max_ev_count, time_wait_ms); - if (0 > ev_count) { - LOG(ERROR) << "epoll wait error: " << strerror(errno); - continue; - } + poller_->Wait(&evs, time_wait_ms); /// 处理事件 - ProcessEvent(evs, ev_count); + ProcessEvent(evs); } // quit App worker_ctx_mgr_->WaitAllWorkerQuit(); - free(evs); - close(epoll_fd_); - epoll_fd_ = -1; quit_.store(true); LOG(INFO) << "app exit exec"; return 0; diff --git a/myframe/app.h b/myframe/app.h index b2afec3..33be462 100644 --- a/myframe/app.h +++ b/myframe/app.h @@ -18,15 +18,15 @@ Author: likepeng #include "myframe/macros.h" #include "myframe/event.h" -struct epoll_event; - namespace myframe { class Msg; +class Poller; class Actor; class ActorContext; class ActorContextManager; class Event; +class EventManager; class EventConn; class EventConnManager; class Worker; @@ -37,7 +37,6 @@ class WorkerContextManager; class ModManager; class App final : public std::enable_shared_from_this { friend class Actor; - friend class ActorContext; public: App(); @@ -76,15 +75,8 @@ class App final : public std::enable_shared_from_this { const std::string& name, std::shared_ptr msg); - std::unique_ptr& GetActorContextManager() { - return actor_ctx_mgr_; - } - std::unique_ptr& GetModManager() { return mods_; } - bool AddEvent(std::shared_ptr ev); - bool DelEvent(std::shared_ptr ev); - int Exec(); void Quit(); @@ -119,11 +111,9 @@ class App final : public std::enable_shared_from_this { void CheckStopWorkers(); /// 分发事件 - EventIOType ToEventIOType(int ev); - int ToEpollType(const EventIOType& type); void DispatchMsg(std::list>* msg_list); void DispatchMsg(std::shared_ptr context); - void ProcessEvent(struct epoll_event* evs, int ev_count); + void ProcessEvent(const std::vector& evs); void ProcessWorkerEvent(std::shared_ptr); void ProcessTimerEvent(std::shared_ptr); void ProcessUserEvent(std::shared_ptr); @@ -138,12 +128,14 @@ class App final : public std::enable_shared_from_this { std::atomic_bool quit_{true}; std::mutex dispatch_mtx_; std::mutex local_mtx_; - /// epoll文件描述符 - int epoll_fd_; + /// poller + std::unique_ptr poller_; /// 模块管理对象 std::unique_ptr mods_; /// 句柄管理对象 std::unique_ptr actor_ctx_mgr_; + /// 事件管理对象 + std::shared_ptr ev_mgr_; /// 与框架通信管理对象 std::unique_ptr ev_conn_mgr_; /// 线程管理对象 diff --git a/myframe/cmd_channel.cpp b/myframe/cmd_channel.cpp index c25d854..a74de0f 100644 --- a/myframe/cmd_channel.cpp +++ b/myframe/cmd_channel.cpp @@ -23,11 +23,11 @@ CmdChannel::~CmdChannel() { CloseSockpair(); } -int CmdChannel::GetOwnerFd() const { +ev_handle_t CmdChannel::GetOwnerHandle() const { return sockpair_[0]; } -int CmdChannel::GetMainFd() const { +ev_handle_t CmdChannel::GetMainHandle() const { return sockpair_[1]; } diff --git a/myframe/cmd_channel.h b/myframe/cmd_channel.h index 4d177fb..bd2e6aa 100644 --- a/myframe/cmd_channel.h +++ b/myframe/cmd_channel.h @@ -6,24 +6,25 @@ Author: likepeng ****************************************************************************/ #pragma once #include "myframe/macros.h" +#include "myframe/event.h" namespace myframe { -enum class Cmd : char { - kQuit = 'q', ///< 退出 - kIdle = 'i', ///< 空闲 - kWaitForMsg = 'w', ///< 等待消息 - kRun = 'r', ///< 运行 - kRunWithMsg = 'm', ///< 运行 -}; - class CmdChannel final { public: + enum class Cmd : char { + kQuit = 'q', ///< 退出 + kIdle = 'i', ///< 空闲 + kWaitForMsg = 'w', ///< 等待消息 + kRun = 'r', ///< 运行 + kRunWithMsg = 'm', ///< 运行(有消息) + }; + CmdChannel(); virtual ~CmdChannel(); - int GetOwnerFd() const; - int GetMainFd() const; + ev_handle_t GetOwnerHandle() const; + ev_handle_t GetMainHandle() const; int SendToOwner(const Cmd& cmd); int RecvFromOwner(Cmd* cmd); @@ -34,7 +35,7 @@ class CmdChannel final { private: void CreateSockpair(); void CloseSockpair(); - int sockpair_[2] {-1, -1}; + ev_handle_t sockpair_[2] {-1, -1}; DISALLOW_COPY_AND_ASSIGN(CmdChannel) }; diff --git a/myframe/event.h b/myframe/event.h index c3ede65..ef7c21c 100644 --- a/myframe/event.h +++ b/myframe/event.h @@ -6,38 +6,34 @@ Author: likepeng ****************************************************************************/ #pragma once #include +#include namespace myframe { -enum class EventIOType : int { - kNone, - kIn, - kOut, -}; - -enum class EventType : int { - kWorkerCommon, - kWorkerTimer, - kWorkerUser, - kEventConn, -}; +typedef int ev_handle_t; class Event : public std::enable_shared_from_this { public: + enum class Type : int { + kWorkerCommon, + kWorkerTimer, + kWorkerUser, + kEventConn, + }; + Event() = default; virtual ~Event() {} /* 事件类型 */ - virtual EventType GetType() { return EventType::kWorkerUser; } + virtual Type GetType() const { return Type::kWorkerUser; } - /* 获得当前事件的文件描述符 */ - virtual int GetFd() const = 0; + /* 事件句柄 */ + virtual ev_handle_t GetHandle() const = 0; - /* 监听的是文件描述符的写事件还是读事件 */ - virtual EventIOType ListenIOType() { return EventIOType::kIn; } + /* 事件名称 */ + virtual std::string GetName() const = 0; - /* 返回的监听事件类型 */ - virtual void RetListenIOType(const EventIOType&) {} + static const ev_handle_t DEFAULT_EV_HANDLE{-1}; }; } // namespace myframe diff --git a/myframe/event_conn.cpp b/myframe/event_conn.cpp index a162e97..a59cc67 100644 --- a/myframe/event_conn.cpp +++ b/myframe/event_conn.cpp @@ -13,9 +13,17 @@ Author: likepeng namespace myframe { -int EventConn::GetFd() const { return cmd_channel_.GetMainFd(); } +ev_handle_t EventConn::GetHandle() const { + return cmd_channel_.GetMainHandle(); +} + +Event::Type EventConn::GetType() const { + return Event::Type::kEventConn; +} -EventType EventConn::GetType() { return EventType::kEventConn; } +std::string EventConn::GetName() const { + return mailbox_.Addr(); +} Mailbox* EventConn::GetMailbox() { return &mailbox_; @@ -28,22 +36,22 @@ CmdChannel* EventConn::GetCmdChannel() { int EventConn::Send( const std::string& dst, std::shared_ptr msg) { - conn_type_ = EventConnType::kSend; + conn_type_ = EventConn::Type::kSend; mailbox_.SendClear(); mailbox_.Send(dst, msg); - cmd_channel_.SendToMain(Cmd::kRun); - Cmd cmd; + cmd_channel_.SendToMain(CmdChannel::Cmd::kRun); + CmdChannel::Cmd cmd; return cmd_channel_.RecvFromMain(&cmd); } const std::shared_ptr EventConn::SendRequest( const std::string& dst, std::shared_ptr req) { - conn_type_ = EventConnType::kSendReq; + conn_type_ = EventConn::Type::kSendReq; mailbox_.SendClear(); mailbox_.Send(dst, req); - cmd_channel_.SendToMain(Cmd::kRunWithMsg); - Cmd cmd; + cmd_channel_.SendToMain(CmdChannel::Cmd::kRunWithMsg); + CmdChannel::Cmd cmd; cmd_channel_.RecvFromMain(&cmd); if (mailbox_.RecvEmpty()) { return nullptr; diff --git a/myframe/event_conn.h b/myframe/event_conn.h index 4f2040f..c108771 100644 --- a/myframe/event_conn.h +++ b/myframe/event_conn.h @@ -15,11 +15,6 @@ Author: likepeng namespace myframe { -enum class EventConnType : char { - kSendReq, - kSend, -}; - class Msg; class EventConnManager; class EventConn final : public Event { @@ -27,12 +22,18 @@ class EventConn final : public Event { friend class EventConnManager; public: + enum class Type : char { + kSendReq, + kSend, + }; + EventConn() = default; - int GetFd() const override; - EventType GetType() override; + ev_handle_t GetHandle() const override; + Event::Type GetType() const override; + std::string GetName() const override; - EventConnType GetConnType() { return conn_type_; } + EventConn::Type GetConnType() { return conn_type_; } int Send( const std::string& dst, @@ -48,7 +49,7 @@ class EventConn final : public Event { CmdChannel cmd_channel_; Mailbox mailbox_; - EventConnType conn_type_{ EventConnType::kSendReq }; + EventConn::Type conn_type_{ EventConn::Type::kSendReq }; DISALLOW_COPY_AND_ASSIGN(EventConn) }; diff --git a/myframe/event_conn_manager.cpp b/myframe/event_conn_manager.cpp index 145103c..633d96c 100644 --- a/myframe/event_conn_manager.cpp +++ b/myframe/event_conn_manager.cpp @@ -9,31 +9,21 @@ Author: likepeng #include -#include "myframe/app.h" #include "myframe/event_conn.h" +#include "myframe/event_manager.h" namespace myframe { -EventConnManager::EventConnManager() { +EventConnManager::EventConnManager(std::shared_ptr ev_mgr) + : ev_mgr_(ev_mgr) { LOG(INFO) << "EventConnManager create"; } EventConnManager::~EventConnManager() { LOG(INFO) << "EventConnManager deconstruct"; - std::lock_guard g(mtx_); - auto app = app_.lock(); - if (app != nullptr) { - for (auto p : run_conn_) { - app->DelEvent(p.second); - } - } - run_conn_.clear(); - run_conn_map_.clear(); - idle_conn_.clear(); } -bool EventConnManager::Init(std::shared_ptr app, int sz) { - app_ = app; +bool EventConnManager::Init(int sz) { for (int i = 0; i < sz; ++i) { std::lock_guard g(mtx_); AddEventConn(); @@ -49,81 +39,47 @@ void EventConnManager::AddEventConn() { conn_sz_++; } -std::shared_ptr EventConnManager::Get(int handle) { - std::lock_guard g(mtx_); - if (run_conn_map_.find(handle) == run_conn_map_.end()) { - DLOG(WARNING) << "can't find event conn, handle " << handle; - return nullptr; - } - auto name = run_conn_map_[handle]; - if (run_conn_.find(name) == run_conn_.end()) { - DLOG(WARNING) << "can't find event conn, name " << name; - return nullptr; - } - return run_conn_[name]; -} - -std::shared_ptr EventConnManager::Get() { +std::shared_ptr EventConnManager::Alloc() { std::lock_guard g(mtx_); // check has event conn if (idle_conn_.empty()) { AddEventConn(); } - auto app = app_.lock(); - if (app == nullptr) { - LOG(ERROR) << "app is nullptr"; - return nullptr; - } // remove from idle_conn auto conn = idle_conn_.front(); idle_conn_.pop_front(); // add to run_conn - const auto& addr = conn->GetMailbox()->Addr(); - run_conn_[addr] = conn; - run_conn_map_[conn->GetFd()] = addr; - // add to epoll - app->AddEvent(conn); + if (!ev_mgr_->Add(conn)) { + return nullptr; + } return conn; } void EventConnManager::Release(std::shared_ptr ev) { - std::lock_guard g(mtx_); - auto app = app_.lock(); - if (app == nullptr) { - LOG(ERROR) << "app is nullptr"; - return; - } - // delete from epoll - app->DelEvent(ev); // remove from run_conn - const auto& name = ev->GetMailbox()->Addr(); - run_conn_.erase(name); - run_conn_map_.erase(ev->GetFd()); + ev_mgr_->Del(ev); // add to idle_conn + std::lock_guard g(mtx_); idle_conn_.emplace_back(ev); } // call by main frame void EventConnManager::Notify( - const std::string& name, + ev_handle_t h, std::shared_ptr msg) { std::shared_ptr ev = nullptr; - { - std::lock_guard g(mtx_); - if (run_conn_.find(name) == run_conn_.end()) { - LOG(WARNING) << "can't find " << name; - return; - } - ev = run_conn_[name]; + ev = ev_mgr_->Get(h); + if (ev == nullptr) { + return; } - if (ev->GetConnType() == EventConnType::kSend) { + if (ev->GetConnType() == EventConn::Type::kSend) { return; } // push msg to event_conn ev->GetMailbox()->Recv(msg); // send cmd to event_conn auto cmd_channel = ev->GetCmdChannel(); - cmd_channel->SendToOwner(Cmd::kIdle); + cmd_channel->SendToOwner(CmdChannel::Cmd::kIdle); } } // namespace myframe diff --git a/myframe/event_conn_manager.h b/myframe/event_conn_manager.h index 4187bb9..e8be907 100644 --- a/myframe/event_conn_manager.h +++ b/myframe/event_conn_manager.h @@ -12,38 +12,33 @@ Author: likepeng #include #include "myframe/macros.h" +#include "myframe/event.h" namespace myframe { -class App; class Msg; +class EventManager; class EventConn; class EventConnManager final { - friend class App; - public: - EventConnManager(); + EventConnManager(std::shared_ptr); virtual ~EventConnManager(); - bool Init(std::shared_ptr app, int sz = 2); - - std::shared_ptr Get(); + bool Init(int sz = 2); - std::shared_ptr Get(int handle); + std::shared_ptr Alloc(); void Release(std::shared_ptr); + void Notify(ev_handle_t, std::shared_ptr msg); + private: void AddEventConn(); - void Notify(const std::string& name, std::shared_ptr msg); int conn_sz_{0}; std::mutex mtx_; - std::unordered_map run_conn_map_; - std::unordered_map> run_conn_; std::list> idle_conn_; - - std::weak_ptr app_; + std::shared_ptr ev_mgr_; DISALLOW_COPY_AND_ASSIGN(EventConnManager) }; diff --git a/myframe/event_manager.cpp b/myframe/event_manager.cpp new file mode 100644 index 0000000..63b2fa3 --- /dev/null +++ b/myframe/event_manager.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ + +#include "myframe/event_manager.h" + +#include + +#include +#include + +namespace myframe { + +EventManager::EventManager() { + LOG(INFO) << "EventManager create"; +} + +EventManager::~EventManager() { + LOG(INFO) << "EventManager deconstruct"; + std::unique_lock lk(rw_); + name_handle_map_.clear(); + evs_.clear(); +} + +ev_handle_t EventManager::ToHandle(const std::string& name) { + std::shared_lock lk(rw_); + if (name_handle_map_.find(name) == name_handle_map_.end()) { + return Event::DEFAULT_EV_HANDLE; + } + return name_handle_map_[name]; +} + +bool EventManager::Has(const std::string& name) { + std::shared_lock lk(rw_); + return name_handle_map_.find(name) != name_handle_map_.end(); +} + +std::vector> EventManager::Get( + const std::vector& type_list) { + std::shared_lock lk(rw_); + std::vector> tmp_evs; + for (auto it = evs_.begin(); it != evs_.end(); ++it) { + for (size_t i = 0; i < type_list.size(); ++i) { + if (type_list[i] == it->second->GetType()) { + tmp_evs.push_back(it->second); + break; + } + } + } + return tmp_evs; +} + +bool EventManager::Add(std::shared_ptr ev) { + auto handle = ev->GetHandle(); + std::unique_lock lk(rw_); + if (evs_.find(handle) != evs_.end()) { + LOG(ERROR) << " add handle " << handle << " has exist"; + return false; + } + evs_[handle] = ev; + name_handle_map_[ev->GetName()] = handle; + return true; +} + +bool EventManager::Del(std::shared_ptr ev) { + auto handle = ev->GetHandle(); + std::unique_lock lk(rw_); + if (evs_.find(handle) == evs_.end()) { + LOG(ERROR) << " del handle " << handle << " has exist"; + return false; + } + evs_.erase(handle); + name_handle_map_.erase(ev->GetName()); + return true; +} + +} // namespace myframe diff --git a/myframe/event_manager.h b/myframe/event_manager.h new file mode 100644 index 0000000..4b97d0c --- /dev/null +++ b/myframe/event_manager.h @@ -0,0 +1,67 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ +#pragma once +#include +#include +#include +#include +#include +#include + +#include "myframe/macros.h" +#include "myframe/event.h" + +namespace myframe { + +class EventConnManager; +class WorkerContextManager; +class EventManager final { + friend class EventConnManager; + friend class WorkerContextManager; + + public: + EventManager(); + virtual ~EventManager(); + + template + std::shared_ptr Get(ev_handle_t h) { + std::shared_lock lk(rw_); + if (evs_.find(h) == evs_.end()) { + return nullptr; + } + return std::dynamic_pointer_cast(evs_[h]); + } + + template + std::shared_ptr Get(const std::string& name) { + std::shared_lock lk(rw_); + if (name_handle_map_.find(name) == name_handle_map_.end()) { + return nullptr; + } + lk.unlock(); + return Get(name_handle_map_[name]); + } + + bool Has(const std::string& name); + + std::vector> Get( + const std::vector&); + + ev_handle_t ToHandle(const std::string&); + + private: + bool Add(std::shared_ptr); + bool Del(std::shared_ptr); + + std::shared_mutex rw_; + std::unordered_map name_handle_map_; + std::unordered_map> evs_; + + DISALLOW_COPY_AND_ASSIGN(EventManager) +}; + +} // namespace myframe diff --git a/myframe/mod_lib.cpp b/myframe/mod_lib.cpp deleted file mode 100644 index c721a92..0000000 --- a/myframe/mod_lib.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -Copyright (c) 2018, likepeng -All rights reserved. - -Author: likepeng -****************************************************************************/ - -#include "myframe/mod_lib.h" - -#include - -#include - -#include "myframe/actor.h" -#include "myframe/worker.h" - -namespace myframe { - -ModLib::ModLib() { pthread_rwlock_init(&rw_, NULL); } - -ModLib::~ModLib() { - pthread_rwlock_wrlock(&rw_); - for (const auto& p : mods_) { - dlclose(p.second); - } - mods_.clear(); - pthread_rwlock_unlock(&rw_); - pthread_rwlock_destroy(&rw_); -} - -std::string ModLib::GetModName(const std::string& full_path) { - auto pos = full_path.find_last_of('/'); - pos = (pos == std::string::npos) ? -1 : pos; - return full_path.substr(pos + 1); -} - -bool ModLib::LoadMod(const std::string& dlpath) { - auto dlname = GetModName(dlpath); - pthread_rwlock_wrlock(&rw_); - if (mods_.find(dlname) != mods_.end()) { - pthread_rwlock_unlock(&rw_); - DLOG(INFO) << dlname << " has loaded"; - return true; - } - - void* dll_handle = dlopen(dlpath.c_str(), RTLD_NOW | RTLD_LOCAL); - if (dll_handle == nullptr) { - pthread_rwlock_unlock(&rw_); - LOG(ERROR) << "Open dll " << dlpath << " failed, " << dlerror(); - return false; - } - mods_[dlname] = dll_handle; - pthread_rwlock_unlock(&rw_); - LOG(INFO) << "Load lib " << dlpath; - return true; -} - -bool ModLib::IsLoad(const std::string& dlname) { - pthread_rwlock_rdlock(&rw_); - auto res = mods_.find(dlname) != mods_.end(); - pthread_rwlock_unlock(&rw_); - return res; -} - -bool ModLib::UnloadMod(const std::string& dlname) { - pthread_rwlock_wrlock(&rw_); - if (mods_.find(dlname) == mods_.end()) { - pthread_rwlock_unlock(&rw_); - return true; - } - - if (dlclose(mods_[dlname])) { - LOG(ERROR) << "lib close failed, " << dlerror(); - } - mods_.erase(dlname); - pthread_rwlock_unlock(&rw_); - return true; -} - -std::shared_ptr ModLib::CreateWorkerInst( - const std::string& mod_name, const std::string& worker_name) { - pthread_rwlock_rdlock(&rw_); - if (mods_.find(mod_name) == mods_.end()) { - LOG(ERROR) << "Find " << mod_name << "." << worker_name << " failed"; - return nullptr; - } - void* handle = mods_[mod_name]; - auto void_func = dlsym(handle, "worker_create"); - auto create = reinterpret_cast(void_func); - if (nullptr == create) { - pthread_rwlock_unlock(&rw_); - LOG(ERROR) - << "Load " << mod_name << "." << worker_name - << " module worker_create function failed"; - return nullptr; - } - auto worker = create(worker_name); - if (nullptr == worker) { - pthread_rwlock_unlock(&rw_); - LOG(ERROR) - << "Create " << mod_name << "." << worker_name - << " failed"; - return nullptr; - } - worker->SetModName(mod_name); - worker->SetTypeName(worker_name); - pthread_rwlock_unlock(&rw_); - return worker; -} - -std::shared_ptr ModLib::CreateActorInst( - const std::string& mod_name, const std::string& actor_name) { - pthread_rwlock_rdlock(&rw_); - if (mods_.find(mod_name) == mods_.end()) { - LOG(ERROR) << "Find " << mod_name << "." << actor_name << " failed"; - return nullptr; - } - void* handle = mods_[mod_name]; - auto void_func = dlsym(handle, "actor_create"); - auto create = reinterpret_cast(void_func); - if (nullptr == create) { - pthread_rwlock_unlock(&rw_); - LOG(ERROR) - << "Load " << mod_name << "." << actor_name - << " module actor_create function failed"; - return nullptr; - } - auto actor = create(actor_name); - if (nullptr == actor) { - pthread_rwlock_unlock(&rw_); - LOG(ERROR) - << "Create " << mod_name << "." << actor_name - << " failed"; - return nullptr; - } - actor->SetModName(mod_name); - actor->SetTypeName(actor_name); - pthread_rwlock_unlock(&rw_); - return actor; -} - -} // namespace myframe diff --git a/myframe/mod_lib.h b/myframe/mod_lib.h deleted file mode 100644 index cbdeb6e..0000000 --- a/myframe/mod_lib.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -Copyright (c) 2018, likepeng -All rights reserved. - -Author: likepeng -****************************************************************************/ - -#pragma once -#include - -#include -#include -#include -#include - -#include "myframe/macros.h" - -namespace myframe { - -class Actor; -class Worker; -class ModLib final { - public: - ModLib(); - virtual ~ModLib(); - - /** - * @brief 是否加载动态库 - * - * @param dlname lib name - * @return true - * @return false - */ - bool IsLoad(const std::string& dlname); - - /** - * @brief 加载模块动态库 - * - * @param dlname full lib path - * @return true - * @return false - */ - bool LoadMod(const std::string& dlpath); - - /** - * @brief 创建actor实例 - * - * @param mod_name eg: libtest.so - * @param actor_name eg: /my/test - * @return std::shared_ptr - */ - std::shared_ptr CreateActorInst( - const std::string& mod_name, - const std::string& actor_name); - - /** - * @brief 创建Worker实例 - * - * @param mod_name eg: libtest.so - * @param worker_name eg: /my/test - * @return Worker* - */ - std::shared_ptr CreateWorkerInst( - const std::string& mod_name, - const std::string& worker_name); - - private: - bool UnloadMod(const std::string& dlname); - std::string GetModName(const std::string& full_path); - - std::unordered_map mods_; - pthread_rwlock_t rw_; - - DISALLOW_COPY_AND_ASSIGN(ModLib) -}; - -} // namespace myframe diff --git a/myframe/mod_manager.cpp b/myframe/mod_manager.cpp index 83034f1..901d6fa 100644 --- a/myframe/mod_manager.cpp +++ b/myframe/mod_manager.cpp @@ -10,6 +10,7 @@ Author: likepeng #include #include +#include "myframe/shared_library.h" #include "myframe/actor.h" #include "myframe/worker.h" @@ -17,90 +18,138 @@ namespace myframe { ModManager::ModManager() { LOG(INFO) << "ModManager create"; - pthread_rwlock_init(&class_actor_rw_, NULL); - pthread_rwlock_init(&class_worker_rw_, NULL); } ModManager::~ModManager() { LOG(INFO) << "ModManager deconstruct"; - pthread_rwlock_destroy(&class_actor_rw_); - pthread_rwlock_destroy(&class_worker_rw_); } bool ModManager::LoadMod(const std::string& dl_path) { - return lib_mods_.LoadMod(dl_path); + auto dlname = GetLibName(dl_path); + std::unique_lock lk(mods_rw_); + if (mods_.find(dlname) != mods_.end()) { + DLOG(INFO) << dlname << " has loaded"; + return true; + } + auto lib = std::make_shared(); + if (!lib->Load(dl_path, SharedLibrary::Flags::kLocal)) { + return false; + } + mods_[dlname] = lib; + LOG(INFO) << "Load lib " << dl_path; + return true; } bool ModManager::RegActor( const std::string& class_name, std::function(const std::string&)> func) { - pthread_rwlock_wrlock(&class_actor_rw_); + std::unique_lock lk(class_actor_rw_); if (class_actors_.find(class_name) != class_actors_.end()) { - pthread_rwlock_unlock(&class_actor_rw_); LOG(WARNING) << "reg " << class_name << " failed, " << " has exist"; return false; } class_actors_[class_name] = func; - pthread_rwlock_unlock(&class_actor_rw_); return true; } bool ModManager::RegWorker( const std::string& class_name, std::function(const std::string&)> func) { - pthread_rwlock_wrlock(&class_worker_rw_); + std::unique_lock lk(class_worker_rw_); if (class_workers_.find(class_name) != class_workers_.end()) { - pthread_rwlock_unlock(&class_worker_rw_); LOG(WARNING) << "reg " << class_name << " failed, " << " has exist"; return false; } class_workers_[class_name] = func; - pthread_rwlock_unlock(&class_worker_rw_); return true; } std::shared_ptr ModManager::CreateActorInst( const std::string& mod_or_class_name, const std::string& actor_name) { - if (lib_mods_.IsLoad(mod_or_class_name)) { - DLOG(INFO) << actor_name << " actor from lib"; - return lib_mods_.CreateActorInst(mod_or_class_name, actor_name); + { + std::shared_lock lk(mods_rw_); + if (mods_.find(mod_or_class_name) != mods_.end()) { + DLOG(INFO) << actor_name << " actor from lib"; + auto lib = mods_[mod_or_class_name]; + auto void_func = lib->GetSymbol("actor_create"); + auto create = reinterpret_cast(void_func); + if (nullptr == create) { + LOG(ERROR) + << "Load " << mod_or_class_name << "." << actor_name + << " module actor_create function failed"; + return nullptr; + } + auto actor = create(actor_name); + if (nullptr == actor) { + LOG(ERROR) + << "Create " << mod_or_class_name << "." << actor_name + << " failed"; + return nullptr; + } + actor->SetModName(mod_or_class_name); + actor->SetTypeName(actor_name); + return actor; + } } - pthread_rwlock_rdlock(&class_actor_rw_); + std::shared_lock lk(class_actor_rw_); if (mod_or_class_name == "class" && class_actors_.find(actor_name) != class_actors_.end()) { DLOG(INFO) << actor_name << " actor from reg class"; auto actor = class_actors_[actor_name](actor_name); actor->SetModName(mod_or_class_name); actor->SetTypeName(actor_name); - pthread_rwlock_unlock(&class_actor_rw_); return actor; } - pthread_rwlock_unlock(&class_actor_rw_); return nullptr; } std::shared_ptr ModManager::CreateWorkerInst( const std::string& mod_or_class_name, const std::string& worker_name) { - if (lib_mods_.IsLoad(mod_or_class_name)) { - LOG(INFO) << "instance worker from lib"; - return lib_mods_.CreateWorkerInst(mod_or_class_name, worker_name); + { + std::shared_lock lk(mods_rw_); + if (mods_.find(mod_or_class_name) != mods_.end()) { + LOG(INFO) << "instance worker from lib"; + auto lib = mods_[mod_or_class_name]; + auto void_func = lib->GetSymbol("worker_create"); + auto create = reinterpret_cast(void_func); + if (nullptr == create) { + LOG(ERROR) + << "Load " << mod_or_class_name << "." << worker_name + << " module worker_create function failed"; + return nullptr; + } + auto worker = create(worker_name); + if (nullptr == worker) { + LOG(ERROR) + << "Create " << mod_or_class_name << "." << worker_name + << " failed"; + return nullptr; + } + worker->SetModName(mod_or_class_name); + worker->SetTypeName(worker_name); + return worker; + } } - pthread_rwlock_rdlock(&class_worker_rw_); + std::shared_lock lk(class_worker_rw_); if (mod_or_class_name == "class" && class_workers_.find(worker_name) != class_workers_.end()) { LOG(INFO) << "instance worker from reg class"; auto worker = class_workers_[worker_name](worker_name); worker->SetModName(mod_or_class_name); worker->SetTypeName(worker_name); - pthread_rwlock_unlock(&class_worker_rw_); return worker; } - pthread_rwlock_unlock(&class_worker_rw_); return nullptr; } +std::string ModManager::GetLibName(const std::string& path) const { + auto pos = path.find_last_of('/'); + pos = (pos == std::string::npos) ? -1 : pos; + return path.substr(pos + 1); +} + } // namespace myframe diff --git a/myframe/mod_manager.h b/myframe/mod_manager.h index 5481c92..aa75c64 100644 --- a/myframe/mod_manager.h +++ b/myframe/mod_manager.h @@ -6,16 +6,20 @@ Author: likepeng ****************************************************************************/ #pragma once +#include +#include #include #include #include #include #include "myframe/macros.h" -#include "myframe/mod_lib.h" namespace myframe { +class Actor; +class Worker; +class SharedLibrary; class ModManager final { public: ModManager(); @@ -39,6 +43,8 @@ class ModManager final { const std::string& mod_or_class_name, const std::string& worker_name); + std::string GetLibName(const std::string& path) const; + private: std::unordered_map< std::string, std::function(const std::string&)>> @@ -46,9 +52,11 @@ class ModManager final { std::unordered_map< std::string, std::function(const std::string&)>> class_workers_; - pthread_rwlock_t class_actor_rw_; - pthread_rwlock_t class_worker_rw_; - ModLib lib_mods_; + std::shared_mutex class_actor_rw_; + std::shared_mutex class_worker_rw_; + + std::unordered_map> mods_; + std::shared_mutex mods_rw_; DISALLOW_COPY_AND_ASSIGN(ModManager) }; diff --git a/myframe/poller.cpp b/myframe/poller.cpp new file mode 100644 index 0000000..500307c --- /dev/null +++ b/myframe/poller.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ + +#include "myframe/poller.h" + +#include +#include + +#include + +namespace myframe { + +Poller::~Poller() { + if (poll_fd_ != -1) { + close(poll_fd_); + poll_fd_ = -1; + } + if (evs_ != nullptr) { + free(evs_); + evs_ = nullptr; + } + init_.store(false); +} + +bool Poller::Init() { + if (init_.load()) { + return true; + } + poll_fd_ = epoll_create(1024); + if (-1 == poll_fd_) { + LOG(ERROR) << "poller create() failed, " << strerror(errno); + return false; + } + LOG(INFO) << "Create epoll fd " << poll_fd_; + auto void_evs = malloc(sizeof(struct epoll_event) * max_ev_count_); + evs_ = reinterpret_cast(void_evs); + init_.store(true); + return true; +} + +bool Poller::Add(const std::shared_ptr& ev) const { + if (!init_.load()) { + return false; + } + struct epoll_event event; + event.data.fd = ev->GetHandle(); + event.events = EPOLLIN; + int res = 0; + // 如果该事件已经注册,就修改事件类型 + res = epoll_ctl(poll_fd_, EPOLL_CTL_MOD, ev->GetHandle(), &event); + if (-1 == res) { + // 没有注册就添加至epoll + res = epoll_ctl(poll_fd_, EPOLL_CTL_ADD, ev->GetHandle(), &event); + if (-1 == res) { + LOG(ERROR) << "epoll_ctl error, " << strerror(errno); + return false; + } + } else { + LOG(WARNING) + << " has already reg ev " << ev->GetHandle() << ": " + << strerror(errno); + return false; + } + return true; +} + +bool Poller::Del(const std::shared_ptr& ev) const { + if (!init_.load()) { + return false; + } + if (-1 == epoll_ctl(poll_fd_, EPOLL_CTL_DEL, ev->GetHandle(), NULL)) { + LOG(ERROR) << "del event " << ev->GetHandle() << ": " << strerror(errno); + return false; + } + return true; +} + +int Poller::Wait(std::vector* evs, int timeout_ms) { + if (!init_.load()) { + return -1; + } + evs->clear(); + int ev_count = epoll_wait(poll_fd_, + evs_, + static_cast(max_ev_count_), + timeout_ms); + if (0 > ev_count) { + LOG(WARNING) << "epoll wait error: " << strerror(errno); + return -1; + } + for (int i = 0; i < ev_count; ++i) { + if (evs_[i].events != EPOLLIN) { + LOG(WARNING) << "epoll event " << evs_[i].events << " continue"; + continue; + } + evs->push_back(evs_[i].data.fd); + } + return ev_count; +} + +} // namespace myframe diff --git a/myframe/poller.h b/myframe/poller.h new file mode 100644 index 0000000..d16dca6 --- /dev/null +++ b/myframe/poller.h @@ -0,0 +1,39 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ + +#pragma once +#include +#include +#include + +#include "myframe/macros.h" +#include "myframe/event.h" + +struct epoll_event; + +namespace myframe { + +class Poller final { + public: + explicit Poller() = default; + ~Poller(); + + bool Init(); + bool Add(const std::shared_ptr&) const; + bool Del(const std::shared_ptr&) const; + int Wait(std::vector* evs, int timeout_ms = 100); + + private: + std::atomic_bool init_{false}; + int poll_fd_{-1}; + size_t max_ev_count_{64}; + struct epoll_event* evs_{nullptr}; + + DISALLOW_COPY_AND_ASSIGN(Poller) +}; + +} // namespace myframe diff --git a/myframe/shared_library.cpp b/myframe/shared_library.cpp new file mode 100644 index 0000000..661fa7c --- /dev/null +++ b/myframe/shared_library.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ + +#include "myframe/shared_library.h" + +#include + +#include + +namespace myframe { + +SharedLibrary::~SharedLibrary() { + Unload(); +} + +bool SharedLibrary::Load(const std::string& path) { + return Load(path, Flags::kGlobal); +} + +bool SharedLibrary::Load( + const std::string& path, + Flags flags) { + std::lock_guard lock(mutex_); + if (handle_ != nullptr) { + return false; + } + int real_flag = RTLD_NOW; + if (static_cast(flags) & static_cast(Flags::kLocal)) { + real_flag |= RTLD_LOCAL; + } else { + real_flag |= RTLD_GLOBAL; + } + handle_ = dlopen(path.c_str(), real_flag); + if (handle_ == nullptr) { + LOG(ERROR) << "Open dll " << path << " failed, " << dlerror(); + return false; + } + path_ = path; + return true; +} + +void SharedLibrary::Unload() { + std::lock_guard lock(mutex_); + if (handle_ == nullptr) { + return; + } + if (dlclose(handle_)) { + LOG(ERROR) << "lib " << path_ << " close failed, " << dlerror(); + } + handle_ = nullptr; +} + +bool SharedLibrary::IsLoaded() { + std::lock_guard lock(mutex_); + return handle_ != nullptr; +} + +bool SharedLibrary::HasSymbol(const std::string& name) { + return GetSymbol(name) != nullptr; +} + +void* SharedLibrary::GetSymbol(const std::string& name) { + std::lock_guard lock(mutex_); + if (handle_ == nullptr) { + return nullptr; + } + + void* result = dlsym(handle_, name.c_str()); + if (result == nullptr) { + LOG(ERROR) << "lib " << path_ + << " has no symbol " << name << ", " << dlerror(); + return nullptr; + } + return result; +} + +} // namespace myframe diff --git a/myframe/shared_library.h b/myframe/shared_library.h new file mode 100644 index 0000000..f8c646b --- /dev/null +++ b/myframe/shared_library.h @@ -0,0 +1,58 @@ +/**************************************************************************** +Copyright (c) 2018, likepeng +All rights reserved. + +Author: likepeng +****************************************************************************/ + +#pragma once +#include +#include +#include +#include + +#include "myframe/macros.h" + +namespace myframe { + +class SharedLibrary { + public: + enum class Flags : int { + // On platforms that use dlopen(), use RTLD_GLOBAL. This is the default + // if no flags are given. + kGlobal = 1, + + // On platforms that use dlopen(), use RTLD_LOCAL instead of RTLD_GLOBAL. + // + // Note that if this flag is specified, RTTI (including dynamic_cast and + // throw) will not work for types defined in the shared library with GCC + // and possibly other compilers as well. See + // http://gcc.gnu.org/faq.html#dso for more information. + kLocal = 2, + }; + + SharedLibrary() = default; + virtual ~SharedLibrary(); + + bool Load(const std::string& path); + bool Load(const std::string& path, Flags flags); + + void Unload(); + + bool IsLoaded(); + + bool HasSymbol(const std::string& name); + + void* GetSymbol(const std::string& name); + + inline const std::string& GetPath() const { return path_; } + + private: + void* handle_{ nullptr }; + std::string path_; + std::mutex mutex_; + + DISALLOW_COPY_AND_ASSIGN(SharedLibrary) +}; + +} // namespace myframe diff --git a/myframe/worker.cpp b/myframe/worker.cpp index a7eaccb..b335f90 100644 --- a/myframe/worker.cpp +++ b/myframe/worker.cpp @@ -42,10 +42,10 @@ int Worker::DispatchMsg() { if (channel == nullptr) { return -1; } - Cmd cmd = Cmd::kIdle; + CmdChannel::Cmd cmd = CmdChannel::Cmd::kIdle; channel->SendToMain(cmd); auto ret = channel->RecvFromMain(&cmd); - if (cmd == Cmd::kQuit) { + if (cmd == CmdChannel::Cmd::kQuit) { LOG(INFO) << GetWorkerName() << " recv stop msg, stoping..."; Stop(); return -1; @@ -58,10 +58,10 @@ int Worker::DispatchAndWaitMsg() { if (channel == nullptr) { return -1; } - Cmd cmd = Cmd::kWaitForMsg; + CmdChannel::Cmd cmd = CmdChannel::Cmd::kWaitForMsg; channel->SendToMain(cmd); auto ret = channel->RecvFromMain(&cmd); - if (cmd == Cmd::kQuit) { + if (cmd == CmdChannel::Cmd::kQuit) { LOG(INFO) << GetWorkerName() << " recv stop msg, stoping..."; Stop(); return -1; @@ -97,8 +97,8 @@ void Worker::SetContext(std::shared_ptr ctx) { ctx_ = ctx; } -EventType Worker::GetType() { - return EventType::kWorkerUser; +Event::Type Worker::GetType() { + return Event::Type::kWorkerUser; } std::shared_ptr Worker::GetApp() { diff --git a/myframe/worker.h b/myframe/worker.h index ea5e4b3..b0e22cb 100644 --- a/myframe/worker.h +++ b/myframe/worker.h @@ -34,7 +34,7 @@ class Worker { * * @return: 事件类型 */ - virtual EventType GetType(); + virtual Event::Type GetType(); /** * GetConfig() - 获得配置参数 diff --git a/myframe/worker_common.h b/myframe/worker_common.h index 288dad3..e0a9af1 100644 --- a/myframe/worker_common.h +++ b/myframe/worker_common.h @@ -26,8 +26,8 @@ class WorkerCommon final : public Worker { void Init() override; void Exit() override; - EventType GetType() override { - return EventType::kWorkerCommon; + Event::Type GetType() override { + return Event::Type::kWorkerCommon; } void SetActorContext(std::shared_ptr context) { diff --git a/myframe/worker_context.cpp b/myframe/worker_context.cpp index 8a8299f..5884829 100644 --- a/myframe/worker_context.cpp +++ b/myframe/worker_context.cpp @@ -29,21 +29,22 @@ WorkerContext::~WorkerContext() { LOG(INFO) << worker_->GetWorkerName() << " deconstruct"; } -int WorkerContext::GetFd() const { - return cmd_channel_.GetMainFd(); +ev_handle_t WorkerContext::GetHandle() const { + return cmd_channel_.GetMainHandle(); } -EventType WorkerContext::GetType() { +Event::Type WorkerContext::GetType() const { return worker_->GetType(); } +std::string WorkerContext::GetName() const { + return worker_->GetWorkerName(); +} + void WorkerContext::Start() { if (runing_.load() == false) { runing_.store(true); - th_ = std::thread( - std::bind( - &WorkerContext::ListenThread, - std::dynamic_pointer_cast(shared_from_this()))); + th_ = std::thread(std::bind(&WorkerContext::ListenThread, this)); } } @@ -62,16 +63,16 @@ void WorkerContext::Initialize() { worker_->Init(); } -void WorkerContext::ListenThread(std::shared_ptr w) { - if (w->worker_ == nullptr) { +void WorkerContext::ListenThread() { + if (worker_ == nullptr) { return; } - w->Initialize(); - while (w->runing_.load()) { - w->worker_->Run(); + Initialize(); + while (runing_.load()) { + worker_->Run(); } - w->worker_->Exit(); - w->cmd_channel_.SendToMain(Cmd::kQuit); + worker_->Exit(); + cmd_channel_.SendToMain(CmdChannel::Cmd::kQuit); } std::size_t WorkerContext::CacheSize() const { @@ -104,7 +105,7 @@ std::shared_ptr WorkerContext::GetApp() { std::ostream& operator<<(std::ostream& out, WorkerContext& ctx) { auto w = ctx.GetWorker(); - out << w->GetWorkerName() << "." << ctx.GetPosixThreadId(); + out << w->GetWorkerName() << "." << ctx.GetThreadId(); return out; } diff --git a/myframe/worker_context.h b/myframe/worker_context.h index 587d916..26cf928 100644 --- a/myframe/worker_context.h +++ b/myframe/worker_context.h @@ -21,15 +21,15 @@ Author: likepeng namespace myframe { -enum class WorkerCtrlOwner : int { - kMain, - kWorker, -}; - class App; class Worker; class WorkerContext final : public Event { public: + enum class CtrlOwner : int { + kMain, + kWorker, + }; + WorkerContext(std::shared_ptr app, std::shared_ptr worker); virtual ~WorkerContext(); @@ -38,11 +38,12 @@ class WorkerContext final : public Event { void Stop(); void Join(); bool IsRuning() { return runing_.load(); } - pthread_t GetPosixThreadId() { return th_.native_handle(); } + std::thread::id GetThreadId() { return th_.get_id(); } /// event 相关函数 - int GetFd() const override; - EventType GetType() override; + ev_handle_t GetHandle() const override; + Event::Type GetType() const override; + std::string GetName() const override; Mailbox* GetMailbox(); @@ -60,10 +61,10 @@ class WorkerContext final : public Event { void Cache(std::list>* msg_list); /// 线程交互控制flag函数 - void SetCtrlOwnerFlag(WorkerCtrlOwner owner) { + void SetCtrlOwnerFlag(CtrlOwner owner) { ctrl_owner_ = owner; } - WorkerCtrlOwner GetOwner() const { + CtrlOwner GetOwner() const { return ctrl_owner_; } void SetWaitMsgQueueFlag(bool in_wait_msg_queue) { @@ -76,12 +77,12 @@ class WorkerContext final : public Event { std::shared_ptr GetApp(); private: - static void ListenThread(std::shared_ptr w); + void ListenThread(); void Initialize(); /// state flag std::atomic_bool runing_; - WorkerCtrlOwner ctrl_owner_{ WorkerCtrlOwner::kWorker }; + CtrlOwner ctrl_owner_{ CtrlOwner::kWorker }; bool in_msg_wait_queue_{ false }; /// worker diff --git a/myframe/worker_context_manager.cpp b/myframe/worker_context_manager.cpp index 36c3a01..e36bf7d 100644 --- a/myframe/worker_context_manager.cpp +++ b/myframe/worker_context_manager.cpp @@ -13,17 +13,18 @@ Author: likepeng #include "myframe/msg.h" #include "myframe/worker.h" #include "myframe/worker_context.h" +#include "myframe/event_manager.h" namespace myframe { -WorkerContextManager::WorkerContextManager() { +WorkerContextManager::WorkerContextManager( + std::shared_ptr ev_mgr) + : ev_mgr_(ev_mgr) { LOG(INFO) << "WorkerContextManager create"; - pthread_rwlock_init(&rw_, NULL); } WorkerContextManager::~WorkerContextManager() { LOG(INFO) << "WorkerContextManager deconstruct"; - pthread_rwlock_destroy(&rw_); } bool WorkerContextManager::Init(int warning_msg_size) { @@ -31,152 +32,102 @@ bool WorkerContextManager::Init(int warning_msg_size) { return true; } -int WorkerContextManager::WorkerSize() { return cur_worker_count_; } - -std::shared_ptr WorkerContextManager::Get(int handle) { - pthread_rwlock_rdlock(&rw_); - if (worker_ctxs_.find(handle) == worker_ctxs_.end()) { - DLOG(WARNING) << "can't find worker, handle " << handle; - pthread_rwlock_unlock(&rw_); - return nullptr; - } - auto ret = worker_ctxs_[handle]; - pthread_rwlock_unlock(&rw_); - return ret; -} - -std::shared_ptr WorkerContextManager::Get( - const std::string& name) { - pthread_rwlock_rdlock(&rw_); - if (name_handle_map_.find(name) == name_handle_map_.end()) { - LOG(ERROR) << "can't find worker, name " << name; - pthread_rwlock_unlock(&rw_); - return nullptr; - } - auto handle = name_handle_map_[name]; - auto ret = worker_ctxs_[handle]; - pthread_rwlock_unlock(&rw_); - return ret; -} +int WorkerContextManager::WorkerSize() { return cur_worker_count_.load(); } bool WorkerContextManager::Add(std::shared_ptr worker_ctx) { - auto worker = worker_ctx->GetWorker(); - int handle = worker_ctx->GetFd(); - pthread_rwlock_wrlock(&rw_); - if (worker_ctxs_.find(handle) != worker_ctxs_.end()) { - LOG(ERROR) << *worker_ctx << " reg handle " << handle - << " has exist"; - pthread_rwlock_unlock(&rw_); + if (!ev_mgr_->Add(worker_ctx)) { return false; } - worker_ctxs_[handle] = worker_ctx; - name_handle_map_[worker->GetWorkerName()] = handle; - ++cur_worker_count_; - pthread_rwlock_unlock(&rw_); + cur_worker_count_.fetch_add(1); return true; } void WorkerContextManager::Del(std::shared_ptr worker_ctx) { - auto worker = worker_ctx->GetWorker(); - int handle = worker_ctx->GetFd(); - pthread_rwlock_wrlock(&rw_); - if (worker_ctxs_.find(handle) == worker_ctxs_.end()) { - pthread_rwlock_unlock(&rw_); + if (!ev_mgr_->Del(worker_ctx)) { return; } + std::unique_lock lk(rw_); stoped_workers_ctx_.push_back(worker_ctx); - worker_ctxs_.erase(worker_ctxs_.find(handle)); - name_handle_map_.erase(worker->GetWorkerName()); - --cur_worker_count_; - pthread_rwlock_unlock(&rw_); + cur_worker_count_.fetch_sub(1); } int WorkerContextManager::IdleWorkerSize() { int sz = 0; - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); sz = idle_workers_ctx_.size(); - pthread_rwlock_unlock(&rw_); return sz; } std::shared_ptr WorkerContextManager::FrontIdleWorker() { std::shared_ptr w = nullptr; - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); if (idle_workers_ctx_.empty()) { - pthread_rwlock_unlock(&rw_); return nullptr; } w = idle_workers_ctx_.front().lock(); - pthread_rwlock_unlock(&rw_); return w; } void WorkerContextManager::PopFrontIdleWorker() { - pthread_rwlock_wrlock(&rw_); + std::unique_lock lk(rw_); if (idle_workers_ctx_.empty()) { - pthread_rwlock_unlock(&rw_); return; } idle_workers_ctx_.pop_front(); - pthread_rwlock_unlock(&rw_); } void WorkerContextManager::PushBackIdleWorker( std::shared_ptr worker) { - pthread_rwlock_wrlock(&rw_); + std::unique_lock lk(rw_); idle_workers_ctx_.emplace_back(worker); - pthread_rwlock_unlock(&rw_); -} - -bool WorkerContextManager::HasWorker(const std::string& name) { - bool res = false; - pthread_rwlock_rdlock(&rw_); - res = (name_handle_map_.find(name) != name_handle_map_.end()); - pthread_rwlock_unlock(&rw_); - return res; } std::vector WorkerContextManager::GetAllUserWorkerAddr() { std::vector res; - pthread_rwlock_rdlock(&rw_); - for (auto p : worker_ctxs_) { - if (p.second->GetType() == EventType::kWorkerUser - && p.second->GetWorker()->GetTypeName() != "node") { - res.push_back(p.second->GetWorker()->GetWorkerName()); + std::shared_lock lk(rw_); + auto worker_ctx_list = ev_mgr_->Get({Event::Type::kWorkerUser}); + for (auto p : worker_ctx_list) { + auto worker_ctx = std::dynamic_pointer_cast(p); + auto worker = worker_ctx->GetWorker(); + // 主要服务与node类型的worker + // 所以返回的地址不包含node + if (worker->GetTypeName() != "node") { + res.push_back(worker->GetWorkerName()); } } - pthread_rwlock_unlock(&rw_); return res; } void WorkerContextManager::StopAllWorker() { - pthread_rwlock_rdlock(&rw_); - for (auto p : worker_ctxs_) { + auto worker_ctx_list = ev_mgr_->Get({ + Event::Type::kWorkerUser, + Event::Type::kWorkerCommon, + Event::Type::kWorkerTimer}); + for (auto p : worker_ctx_list) { + auto worker_ctx = std::dynamic_pointer_cast(p); // 目前仅支持使用channel通信的worker停止退出 // 不使用的可以调用Stop函数退出(目前暂无需求) - // p.second->Stop(); - p.second->GetCmdChannel()->SendToOwner(Cmd::kQuit); + // worker_ctx->Stop(); + worker_ctx->GetCmdChannel()->SendToOwner(CmdChannel::Cmd::kQuit); } - pthread_rwlock_unlock(&rw_); } void WorkerContextManager::WaitAllWorkerQuit() { // FIXME(likepeng): 只支持退出时释放worker资源 // 运行时释放worker资源有可能导致主线程阻塞,影响其它组件调度 - pthread_rwlock_rdlock(&rw_); + std::shared_lock lk(rw_); for (auto p : stoped_workers_ctx_) { p->Join(); } - pthread_rwlock_unlock(&rw_); } void WorkerContextManager::PushWaitWorker( std::shared_ptr worker) { - worker->SetCtrlOwnerFlag(WorkerCtrlOwner::kMain); + worker->SetCtrlOwnerFlag(WorkerContext::CtrlOwner::kMain); } void WorkerContextManager::WeakupWorker() { - pthread_rwlock_wrlock(&rw_); + std::unique_lock lk(rw_); for (auto it = weakup_workers_ctx_.begin(); it != weakup_workers_ctx_.end();) { auto worker_ctx = it->lock(); @@ -184,32 +135,31 @@ void WorkerContextManager::WeakupWorker() { it = weakup_workers_ctx_.erase(it); continue; } - if (worker_ctx->GetOwner() == WorkerCtrlOwner::kWorker) { + if (worker_ctx->GetOwner() == WorkerContext::CtrlOwner::kWorker) { ++it; continue; } worker_ctx->GetMailbox()->Recv(worker_ctx->GetCache()); it = weakup_workers_ctx_.erase(it); - worker_ctx->SetCtrlOwnerFlag(WorkerCtrlOwner::kWorker); + worker_ctx->SetCtrlOwnerFlag(WorkerContext::CtrlOwner::kWorker); worker_ctx->SetWaitMsgQueueFlag(false); DLOG(INFO) << "notify " << *worker_ctx << " process msg"; - worker_ctx->GetCmdChannel()->SendToOwner(Cmd::kRunWithMsg); + worker_ctx->GetCmdChannel()->SendToOwner(CmdChannel::Cmd::kRunWithMsg); } - pthread_rwlock_unlock(&rw_); } void WorkerContextManager::DispatchWorkerMsg(std::shared_ptr msg) { std::string worker_name = msg->GetDst(); - if (name_handle_map_.find(worker_name) == name_handle_map_.end()) { + if (!ev_mgr_->Has(worker_name)) { LOG(ERROR) << "can't find worker " << worker_name << ", drop msg: from " << msg->GetSrc() << " to " << msg->GetDst(); return; } - auto worker_ctx = Get(worker_name); + auto worker_ctx = ev_mgr_->Get(worker_name); auto worker = worker_ctx->GetWorker(); auto worker_type = worker->GetType(); - if (worker_type == EventType::kWorkerTimer || - worker_type == EventType::kWorkerCommon) { + if (worker_type == Event::Type::kWorkerTimer || + worker_type == Event::Type::kWorkerCommon) { LOG(WARNING) << worker_name << " unsupport recv msg, drop it"; return; } @@ -223,9 +173,8 @@ void WorkerContextManager::DispatchWorkerMsg(std::shared_ptr msg) { return; } worker_ctx->SetWaitMsgQueueFlag(true); - pthread_rwlock_wrlock(&rw_); + std::unique_lock lk(rw_); weakup_workers_ctx_.emplace_back(worker_ctx); - pthread_rwlock_unlock(&rw_); } } // namespace myframe diff --git a/myframe/worker_context_manager.h b/myframe/worker_context_manager.h index 98516bd..9f0d524 100644 --- a/myframe/worker_context_manager.h +++ b/myframe/worker_context_manager.h @@ -6,8 +6,8 @@ Author: likepeng ****************************************************************************/ #pragma once -#include - +#include +#include #include #include #include @@ -16,22 +16,22 @@ Author: likepeng #include #include "myframe/macros.h" +#include "myframe/event.h" namespace myframe { class Msg; +class EventManager; class WorkerContext; class WorkerContextManager final { public: - WorkerContextManager(); + WorkerContextManager(std::shared_ptr); virtual ~WorkerContextManager(); bool Init(int warning_msg_size = 10); int WorkerSize(); - std::shared_ptr Get(int fd); - std::shared_ptr Get(const std::string&); bool Add(std::shared_ptr worker); void Del(std::shared_ptr worker); @@ -47,7 +47,6 @@ class WorkerContextManager final { void DispatchWorkerMsg(std::shared_ptr msg); std::vector GetAllUserWorkerAddr(); - bool HasWorker(const std::string& name); // 停止工作线程 void StopAllWorker(); @@ -58,17 +57,15 @@ class WorkerContextManager final { /// 工作线程数(包含用户线程) std::atomic_int cur_worker_count_{0}; /// 读写锁 - pthread_rwlock_t rw_; + std::shared_mutex rw_; /// 空闲线程链表 std::list> idle_workers_ctx_; /// 有消息user线程 std::list> weakup_workers_ctx_; /// 停止的线程列表 std::list> stoped_workers_ctx_; - /// name/handle 映射表 - std::unordered_map name_handle_map_; - /// handle/worker 映射表 - std::unordered_map> worker_ctxs_; + /// 事件管理对象 + std::shared_ptr ev_mgr_; DISALLOW_COPY_AND_ASSIGN(WorkerContextManager) }; diff --git a/myframe/worker_timer.h b/myframe/worker_timer.h index 739d54c..b3a91e8 100644 --- a/myframe/worker_timer.h +++ b/myframe/worker_timer.h @@ -88,8 +88,8 @@ class WorkerTimer final : public Worker { void Init() override; void Run() override; void Exit() override; - EventType GetType() override { - return EventType::kWorkerTimer; + Event::Type GetType() override { + return Event::Type::kWorkerTimer; } private: diff --git a/templates/CMakeLists.txt b/templates/CMakeLists.txt index 9373701..c690e6f 100644 --- a/templates/CMakeLists.txt +++ b/templates/CMakeLists.txt @@ -2,14 +2,11 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.10) PROJECT(@template_name@) #### compile setting -SET(CMAKE_C_STANDARD 11) SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD_REQUIRED YES) -SET(CMAKE_C_FLAGS "-fPIC -Werror=return-type -Werror=return-local-addr") -SET(CMAKE_CXX_FLAGS "-fPIC -Werror=return-type -Werror=return-local-addr") +SET(CMAKE_CXX_FLAGS "-fPIC -Wall -Wextra -Werror") #### path setting -SET(CMAKE_INSTALL_PREFIX "$ENV{HOME}/myframe") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") SET(MYFRAME_INSTALL_SERVICE_DIR ${CMAKE_INSTALL_PREFIX}/service) SET(MYFRAME_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib) @@ -20,7 +17,7 @@ FIND_PACKAGE(gflags REQUIRED) FIND_PACKAGE(GTest REQUIRED) #### include directory -INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/inc) +INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include) #### deps libs LINK_LIBRARIES( @@ -48,9 +45,6 @@ INSTALL(TARGETS ${PROJECT_NAME} FILE(GLOB conf_files "*.json") INSTALL(FILES ${conf_files} - PERMISSIONS - OWNER_READ - GROUP_READ - WORLD_READ + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ DESTINATION ${MYFRAME_INSTALL_SERVICE_DIR} ) diff --git a/templates/template.cpp b/templates/template.cpp index be21410..c70a627 100644 --- a/templates/template.cpp +++ b/templates/template.cpp @@ -18,6 +18,7 @@ class @template_name@Actor : public myframe::Actor { public: /* actor模块加载完毕后调用 */ int Init(const char* param) override { + (void)param; return 0; } diff --git a/tools/gen_mod_proj.py b/tools/gen_mod_proj.py index c7dfba9..ff31d66 100644 --- a/tools/gen_mod_proj.py +++ b/tools/gen_mod_proj.py @@ -6,12 +6,12 @@ import shutil def dumpUsage(): - print("Usage: python3 ~/myframe/tools/gen_mod_proj.py --name=MOD_NAME --dir=MOD_DIR") + print("Usage: python3 gen_mod_proj.py --name=MOD_NAME --dir=MOD_DIR") print("Options:") print(" --name MOD_NAME Base module name, for example: usermod") print(" --dir MOD_DIR Base module project dirtory, for example: /home/yourname/") print("") - print("Sample: python3 ~/myframe/tools/gen_mod_proj.py --name=\"usermod\" --dir=\"/home/yourname/\"") + print("Sample: python3 gen_mod_proj.py --name=\"usermod\" --dir=\"/home/yourname/\"") print("") def checkParams(opts): @@ -72,11 +72,11 @@ def replaceFile(params, file): dumpUsage() sys.exit(1) - proj_src_dir = "" + proj_src_dir = os.path.split(os.path.realpath(__file__))[0] proj_rename_dict = {} proj_modify_var_list = [] # 设置要修改的文件 - proj_src_dir = os.environ['HOME'] + "/myframe/templates/" + proj_src_dir = proj_src_dir + "/../templates/" proj_rename_dict[params_dict["dir"] + "template.cpp"] = params_dict["dir"] + params_dict["name"] + ".cpp" proj_rename_dict[params_dict["dir"] + "template.json"] = params_dict["dir"] + params_dict["name"] + ".json" proj_modify_var_list.append(params_dict["dir"] + "CMakeLists.txt") @@ -95,4 +95,3 @@ def replaceFile(params, file): replaceFile(params_dict, v) print("Success!!!") - \ No newline at end of file