├── .clang-tidy
├── .gitignore
├── .travis.yml
├── CMakeLists.txt
├── Cppnet.sln
├── Cppnet.vcxproj
├── Cppnet.vcxproj.filters
├── LICENSE
├── README.md
├── README_cn.md
├── TODO.md
├── build.sh
├── common
├── CMakeLists.txt
├── alloter
│ ├── alloter_interface.h
│ ├── normal_alloter.cpp
│ ├── normal_alloter.h
│ ├── pool_alloter.cpp
│ ├── pool_alloter.h
│ ├── pool_block.cpp
│ └── pool_block.h
├── buffer
│ ├── buffer_block.cpp
│ ├── buffer_block.h
│ ├── buffer_interface.h
│ ├── buffer_queue.cpp
│ └── buffer_queue.h
├── log
│ ├── base_logger.cpp
│ ├── base_logger.h
│ ├── file_logger.cpp
│ ├── file_logger.h
│ ├── log.cpp
│ ├── log.h
│ ├── log_stream.cpp
│ ├── log_stream.h
│ ├── logger_interface.h
│ ├── stdout_logger.cpp
│ └── stdout_logger.h
├── network
│ ├── address.cpp
│ ├── address.h
│ ├── io_handle.h
│ ├── posix
│ │ ├── io_handle.cpp
│ │ └── socket.cpp
│ ├── socket.h
│ └── win
│ │ ├── io_handle.cpp
│ │ └── socket.cpp
├── os
│ ├── convert.h
│ ├── os_info.cpp
│ ├── os_info.h
│ ├── posix
│ │ └── convert.cpp
│ └── win
│ │ └── convert.cpp
├── structure
│ ├── list.h
│ ├── list_slot.h
│ ├── thread_safe_block_queue.h
│ ├── thread_safe_queue.h
│ └── thread_safe_unordered_map.h
├── thread
│ ├── thread.h
│ └── thread_with_queue.h
├── timer
│ ├── timer.cpp
│ ├── timer.h
│ ├── timer_container.cpp
│ ├── timer_container.h
│ ├── timer_interface.h
│ ├── timer_slot.cpp
│ └── timer_slot.h
└── util
│ ├── any.h
│ ├── bitmap.cpp
│ ├── bitmap.h
│ ├── config.cpp
│ ├── config.h
│ ├── os_return.h
│ ├── random.cpp
│ ├── random.h
│ ├── singleton.h
│ ├── time.cpp
│ └── time.h
├── cppnet
├── CMakeLists.txt
├── cppnet.cpp
├── cppnet_base.cpp
├── cppnet_base.h
├── cppnet_config.h
├── dispatcher.cpp
├── dispatcher.h
├── event
│ ├── action_interface.h
│ ├── epoll
│ │ ├── epoll_action.cpp
│ │ ├── epoll_action.h
│ │ └── wepoll
│ │ │ ├── README.md
│ │ │ ├── wepoll.c
│ │ │ └── wepoll.h
│ ├── event_interface.cpp
│ ├── event_interface.h
│ ├── kqueue
│ │ ├── kqueue_action.cpp
│ │ └── kqueue_action.h
│ ├── timer_event.cpp
│ └── timer_event.h
└── socket
│ ├── connect_socket.cpp
│ ├── connect_socket.h
│ ├── rw_socket.cpp
│ ├── rw_socket.h
│ ├── socket_interface.cpp
│ └── socket_interface.h
├── doc
├── api
│ ├── api.md
│ └── api_cn.md
├── build
│ ├── build.md
│ └── build_cn.md
├── efficiency
│ ├── apache_ab_bench.md
│ └── apache_ab_bench_cn.md
├── image
│ ├── cppnet_level.png
│ ├── linux_apache_ab_bench.png
│ ├── logo.png
│ ├── macos_apache_ab_bench.png
│ └── windows_apache_ab_bench.png
├── introduction
│ └── cppnet.md
└── start
│ ├── quick_start.md
│ └── quick_start_cn.md
├── include
├── cppnet.h
├── cppnet_buffer.h
├── cppnet_socket.h
└── cppnet_type.h
├── makefile
└── test
├── CMakeLists.txt
├── echo
├── CMakeLists.txt
├── echo_client.cpp
├── echo_client.vcxproj
├── echo_server.cpp
├── echo_server.vcxproj
└── makefile
├── http
├── CMakeLists.txt
├── http.vcxproj
├── http.vcxproj.user
├── http_context.cpp
├── http_context.h
├── http_request.h
├── http_response.cpp
├── http_response.h
├── http_server.cpp
├── http_server.h
├── http_server_test.cpp
└── makefile
├── multi_port
├── CMakeLists.txt
├── makefile
├── multi_port_client.cpp
├── multi_port_client.filters
├── multi_port_client.vcxproj
├── multi_port_server.cpp
├── multi_port_server.filters
└── multi_port_server.vcxproj
├── pingpong
├── CMakeLists.txt
├── client.cpp
├── client.vcxproj
├── client.vcxproj.filters
├── makefile
├── server.cpp
├── server.vcxproj
└── server.vcxproj.filters
├── rpc
├── CMakeLists.txt
├── client.cpp
├── common_struct.h
├── func_thread.cpp
├── func_thread.h
├── info_router.cpp
├── info_router.h
├── makefile
├── parse_package.cpp
├── parse_package.h
├── rpc_client.cpp
├── rpc_client.h
├── rpc_client.vcxproj
├── rpc_client.vcxproj.filters
├── rpc_server.cpp
├── rpc_server.h
├── rpc_server.vcxproj
├── rpc_server.vcxproj.filters
└── server.cpp
├── sendfile
├── CMakeLists.txt
├── common.h
├── makefile
├── md5.cpp
├── md5.h
├── send_file_cli.vcxproj.vcxproj
├── send_file_client.cpp
├── send_file_ser.vcxproj.vcxproj
└── send_file_server.cpp
└── simple
├── CMakeLists.txt
├── client.filters
├── client.vcxproj
├── cppnet_client.cpp
├── cppnet_server.cpp
├── makefile
├── server.vcxproj
└── server.vcxproj.filters
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore all files without extension.
2 | # If you need to git-add a file without extension, add -f
3 | *
4 | !*.*
5 | !*/
6 | build/
7 | *.o
8 | *.a
9 | *.log
10 | *.vs
11 | *64
12 | *32
13 | *.db
14 | *vscode
15 | *DEBUG
16 | *RELEASE
17 | *.pro
18 | *.user
19 | *bug
20 |
21 | # compdb files
22 | .cache/
23 | compile_commands.json
24 | .clangd/
25 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | sudo: required
3 | dist: trusty
4 |
5 | compiler:
6 | - gcc
7 |
8 | os:
9 | - linux
10 |
11 | script:
12 | - if [ $TRAVIS_OS_NAME == linux ]; then sh build.sh; fi
13 |
14 | branches:
15 | only:
16 | - master
17 |
18 | notifications:
19 | email: false
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(cppnet C CXX)
4 |
5 | set(CMAKE_CXX_STANDARD 11)
6 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
7 |
8 | set(CXX_FLAGS
9 | -O2
10 | -std=c++11
11 | -rdynamic
12 | -lpthread
13 | -fPIC
14 | -lstdc++
15 | -pipe
16 | )
17 |
18 | if(CMAKE_BUILD_BITS EQUAL 32)
19 | list(APPEND CXX_FLAGS "-m32")
20 | else()
21 | list(APPEND CXX_FLAGS "-m64")
22 | endif()
23 |
24 | if (WIN32)
25 | add_definitions(-D__win__)
26 | add_definitions(-D__use_iocp__)
27 | endif ()
28 |
29 | # output
30 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
31 | set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
32 |
33 | # include
34 | include_directories(${CMAKE_CURRENT_SOURCE_DIR})
35 |
36 | add_subdirectory(common)
37 | add_subdirectory(cppnet)
38 |
39 | add_library(${PROJECT_NAME} STATIC ${common_source} ${cppnet_source})
40 |
41 | add_subdirectory(test)
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, caozhiyi
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |

2 |
3 |
4 |
5 |
6 |
7 |
8 | See [chinese](/README_cn.md)
9 | See the details in chinese [wiki](https://github.com/caozhiyi/CppNet/wiki)
10 | ## Introduction
11 |
12 | Cppnet is a proactor mode and multithreaded network with C++11 on tcp. Support Window, Linux and macOS.
13 | - `Simple`:
14 | + Only export a little interfaces, all net io insterface are asynchronous callbacks
15 | + Insterface as much as possible like calling the socket API of the system
16 | + There is only one additional buffer interface for the client
17 | + Support both IPv4 and IPv6
18 |
19 | - `Fast`:
20 | + Use epoll, [wepoll](https://github.com/piscisaureus/wepoll) and kqueue
21 | + Multithreaded threads are handled by the kernel
22 | + Each socket has a single memory pool object. All memory requested from the memory pool is managed by an intelligent pointer
23 | + Using time wheel to realize timer
24 |
25 | - `Clear`:
26 | + Three layers: event-driven layer, session management layer and interface layer
27 | + Upward notification through callbacks between layers. Clear division of responsibilities among modules, pay to Caesar what belongs to Caesar and God what belongs to God
28 | + The interface decoupling module is used to meet the minimum interface principle and dependency inversion principle
29 |
30 | ## Quick Start
31 | Quick use of `cppnet` and precautions, see [quick start](doc/start/quick_start.md).
32 |
33 | ## Interface
34 |
35 | `cppnet` has three types of external interfaces, which are also defined in three header files
36 | - Initialization and global configuration, defined in [cppnet](/include/cppnet.h)
37 | - `socket` operation, defined in [cppnet_socket](/include/cppnet_socket.h)
38 | - `buffer` read, defined in [cppnet_buffer](/include/cppnet_buffer.h)
39 |
40 | For details, see [API](/doc/api/api.md).
41 |
42 | ## Example
43 |
44 | All simples are in [test](/test):
45 | - [simple](/test/simple): Most simple example.
46 | - [echo](/test/echo): Test program of echo with 200 connection.
47 | - [http](/test/http): Simple HTTP server is implemented with reference to muduo.
48 | - [sendfile](/test/sendfile): Example of sending and receiving files.
49 | - [pingpong](/test/pingpong): Pingpong test program.
50 | - [rpc](/test/rpc): Interesting rpc program.
51 | - [multi_port](/test/multi_port): Example of multiple listening ports.
52 |
53 | ## Efficiency
54 |
55 | Apache `ab` is used to pressure test the `http` test service in the [test](/test) directory, and compared with `muduo`.
56 | For details, see [ab benchmark](/doc/efficiency/apache_ab_bench.md)。
57 |
58 | ## Build
59 |
60 | Look at [Build](/doc/build/build.md)
61 |
62 | ## Licenses
63 |
64 | This program is under the terms of the BSD 3-Clause License. For details, see [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause).
65 |
--------------------------------------------------------------------------------
/README_cn.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 |
6 |
7 |
8 | 查看更多细节 [wiki](https://github.com/caozhiyi/CppNet/wiki)
9 |
10 | ## 简介
11 |
12 | Cppnet是一个封装在TCP协议上的proactor模式multi-thread C++11网络库,支持在windows,linux以及macOS上编译使用。
13 | - `简单`:
14 | + 对外暴漏最少接口,所有的网络响应都封装为异步回调的形式
15 | + 接口声明类似系统原生
16 | + 只新增一个buffer接口集
17 | + 支持IPv6和IPv4
18 |
19 | - `快速`:
20 | + 分别采用epoll,[wepoll](https://github.com/piscisaureus/wepoll),kqueue做底层事件驱动
21 | + 多线程惊群交由内核处理
22 | + 参照SGI STL和Nginx实现了内存池,每个连接都独享一个内存池对象,所有从内存池中申请的内存都由智能指针管理
23 | + 用时间轮实现定时器
24 |
25 | - `明了`:
26 | + 结构上分为三层:事件驱动层,会话管理层,接口层,各层之间通过回调向上通知
27 | + 各个模块之间职责分工明确,上帝的事儿归上帝管,凯撒的事儿归凯撒管
28 | + 通过接口解耦模块,符合最小接口原则和依赖倒置原则
29 |
30 | ## 快速开始
31 | 快速使用`cppnet`,以及使用注意事项,请看[快速开始](doc/start/quick_start_cn.md)。
32 |
33 | ## 接口
34 |
35 | `cppnet`对外接口主要包括三种类型,也分别定义在三个头文件中:
36 | - 初始化和全局配置类,定义在[cppnet](/include/cppnet.h)
37 | - `socket`操作类,[cppnet_socket](/include/cppnet_socket.h)
38 | - `buffer`读取类,定义在[cppnet_buffer](/include/cppnet_buffer.h)
39 |
40 | 接口详情请参考[API](/doc/api/api_cn.md)。
41 |
42 | ## 示例
43 |
44 | 所有示例都在 [test](/test) 目录下:
45 | - [simple](/test/simple): 一个简单的使用示例。
46 | - [echo](/test/echo): 实现了200连接量的echo的测试程序。
47 | - [http](/test/http): 参照muduo实现了一个简单的http服务器。
48 | - [sendfile](/test/sendfile): 文件发送和接收示例。
49 | - [pingpong](/test/pingpong): pingpong测试程序。
50 | - [rpc](/test/rpc): 简单的rpc示例。
51 | - [multi_port](/test/multi_port): 多监听端口示例。
52 |
53 | ## 效率
54 |
55 | 目前用Apache `ab` 对[test](/test)目录中的`http`测试服务做了压测,并与`muduo`做了对比。
56 | 详情请看[ab压测](/doc/efficiency/apache_ab_bench_cn.md)。
57 |
58 | ## 编译
59 |
60 | 请看[编译](/doc/build/build_cn.md)
61 |
62 | ## Q&A
63 | 1. 为什么在windows上不使用IOCP?
64 | 请看文章[cppnet网络库](/doc/introduction/cppnet.md)最后一节。
65 |
66 | ## 协议
67 |
68 | CppNet使用BSD 3-Clause使用条款,详情请看[BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)。
69 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | - [x] IOCP supports multiple accept events
2 | - [x] logger support stream
3 | - [x] support IPV6
4 | - [x] remove default thread number to iocp
5 | - [x] format files name
6 | - [x] restruct event action support iocp
7 | - [x] add thread safe alloter
8 | - [x] valgrind check memory
9 | - [x] ab performance testing
10 | - [x] update document
11 | - [x] client socket add accept socket number
12 | - [x] delete cppnet instance destory lib
13 | - [x] add socket content
14 | - [x] multi listen port example
15 | - [x] pingpong test on windows
16 | - [x] quick start document
17 | - [ ] pingpong performance testing
18 | - [ ] IOCP lost disconnection event
19 | - [ ] windows timer wakeup other thread
20 | - [ ] memory leak check
21 | - [ ] windows use wepoll
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | make -j4
--------------------------------------------------------------------------------
/common/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(cppnet CXX)
4 |
5 | aux_source_directory(${PROJECT_SOURCE_DIR}/alloter src_files)
6 | aux_source_directory(${PROJECT_SOURCE_DIR}/buffer src_files)
7 | aux_source_directory(${PROJECT_SOURCE_DIR}/log src_files)
8 | aux_source_directory(${PROJECT_SOURCE_DIR}/os src_files)
9 | aux_source_directory(${PROJECT_SOURCE_DIR}/network src_files)
10 | aux_source_directory(${PROJECT_SOURCE_DIR}/structure src_files)
11 | aux_source_directory(${PROJECT_SOURCE_DIR}/thread src_files)
12 | aux_source_directory(${PROJECT_SOURCE_DIR}/timer src_files)
13 | aux_source_directory(${PROJECT_SOURCE_DIR}/util src_files)
14 |
15 | IF (WIN32)
16 | aux_source_directory(${PROJECT_SOURCE_DIR}/network/win src_files)
17 | aux_source_directory(${PROJECT_SOURCE_DIR}/os/win src_files)
18 | ELSEIF (APPLE)
19 | aux_source_directory(${PROJECT_SOURCE_DIR}/network/posix src_files)
20 | aux_source_directory(${PROJECT_SOURCE_DIR}/os/posix src_files)
21 | ELSEIF (UNIX)
22 | aux_source_directory(${PROJECT_SOURCE_DIR}/network/posix src_files)
23 | aux_source_directory(${PROJECT_SOURCE_DIR}/os/posix src_files)
24 | ENDIF ()
25 |
26 | set(common_source ${src_files} PARENT_SCOPE)
--------------------------------------------------------------------------------
/common/alloter/alloter_interface.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_ALLOTER_ALLOTER_INTERFACE
7 | #define COMMON_ALLOTER_ALLOTER_INTERFACE
8 |
9 | #include
10 | #include
11 |
12 | namespace cppnet {
13 |
14 | static const uint16_t __align = sizeof(unsigned long);
15 |
16 | class Alloter {
17 | public:
18 | Alloter() {}
19 | virtual ~Alloter() {}
20 |
21 | virtual void* Malloc(uint32_t size) = 0;
22 | virtual void* MallocAlign(uint32_t size) = 0;
23 | virtual void* MallocZero(uint32_t size) = 0;
24 |
25 | virtual void Free(void* &data, uint32_t len = 0) = 0;
26 |
27 | protected:
28 | uint32_t Align(uint32_t size) {
29 | return ((size + __align - 1) & ~(__align - 1));
30 | }
31 | };
32 |
33 | class AlloterWrap {
34 | public:
35 | AlloterWrap(std::shared_ptr a) : _alloter(a) {}
36 | ~AlloterWrap() {}
37 |
38 | //for object. invocation of constructors and destructors
39 | template
40 | T* PoolNew(Args&&... args);
41 | template
42 | std::shared_ptr PoolNewSharePtr(Args&&... args);
43 |
44 | template
45 | void PoolDelete(T* &c);
46 |
47 | //for continuous memory
48 | template
49 | T* PoolMalloc(uint32_t size);
50 | template
51 | std::shared_ptr PoolMallocSharePtr(uint32_t size);
52 |
53 | template
54 | void PoolFree(T* &m, uint32_t len);
55 |
56 | private:
57 | std::shared_ptr _alloter;
58 | };
59 |
60 | template
61 | T* AlloterWrap::PoolNew(Args&&... args) {
62 | uint32_t sz = sizeof(T);
63 |
64 | void* data = _alloter->MallocAlign(sz);
65 | if (!data) {
66 | return nullptr;
67 | }
68 |
69 | T* res = new(data) T(std::forward(args)...);
70 | return res;
71 | }
72 |
73 | template
74 | std::shared_ptr AlloterWrap::PoolNewSharePtr(Args&&... args) {
75 | T* ret = PoolNew(std::forward(args)...);
76 | return std::shared_ptr(ret, [this](T* c) { PoolDelete(c); });
77 | }
78 |
79 | template
80 | void AlloterWrap::PoolDelete(T* &c) {
81 | if (!c) {
82 | return;
83 | }
84 |
85 | c->~T();
86 |
87 | uint32_t len = sizeof(T);
88 | void* data = (void*)c;
89 | _alloter->Free(data, len);
90 | c = nullptr;
91 | }
92 |
93 | template
94 | T* AlloterWrap::PoolMalloc(uint32_t sz) {
95 | return (T*)_alloter->MallocAlign(sz);
96 | }
97 |
98 | template
99 | std::shared_ptr AlloterWrap::PoolMallocSharePtr(uint32_t size) {
100 | T* ret = PoolMalloc(size);
101 | return std::shared_ptr(ret, [this, size](T* &c) { PoolFree(c, size); });
102 | }
103 |
104 | template
105 | void AlloterWrap::PoolFree(T* &m, uint32_t len) {
106 | if (!m) {
107 | return;
108 | }
109 | void* data = (void*)m;
110 | _alloter->Free(data, len);
111 | m = nullptr;
112 | }
113 |
114 | }
115 |
116 | #endif
--------------------------------------------------------------------------------
/common/alloter/normal_alloter.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include //for memset
7 | #include
8 | #include "common/alloter/normal_alloter.h"
9 |
10 | namespace cppnet {
11 |
12 | NormalAlloter::NormalAlloter() {
13 |
14 | }
15 |
16 | NormalAlloter::~NormalAlloter() {
17 |
18 | }
19 |
20 | void* NormalAlloter::Malloc(uint32_t size) {
21 | void* ret = malloc((size_t)size);
22 | if (!ret) {
23 | throw "not enough memory";
24 | return nullptr;
25 | }
26 |
27 | return ret;
28 | }
29 |
30 | void* NormalAlloter::MallocAlign(uint32_t size) {
31 | return Malloc(Align(size));
32 | }
33 |
34 | void* NormalAlloter::MallocZero(uint32_t size) {
35 | void* ret = Malloc(size);
36 | if (ret) {
37 | memset(ret, 0, size);
38 | }
39 | return ret;
40 | }
41 |
42 | void NormalAlloter::Free(void* &data, uint32_t len) {
43 | free(data);
44 | data = nullptr;
45 | }
46 |
47 | std::shared_ptr MakeNormalAlloterPtr() {
48 | return std::make_shared();
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/common/alloter/normal_alloter.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_ALLOTER_NORMAL_ALLOTER
7 | #define COMMON_ALLOTER_NORMAL_ALLOTER
8 |
9 | #include "common/alloter/alloter_interface.h"
10 |
11 | namespace cppnet {
12 |
13 | class NormalAlloter : public Alloter {
14 | public:
15 | NormalAlloter();
16 | ~NormalAlloter();
17 |
18 | void* Malloc(uint32_t size);
19 | void* MallocAlign(uint32_t size);
20 | void* MallocZero(uint32_t size);
21 |
22 | void Free(void* &data, uint32_t len = 0);
23 | };
24 |
25 | std::shared_ptr MakeNormalAlloterPtr();
26 |
27 | }
28 |
29 | #endif
--------------------------------------------------------------------------------
/common/alloter/pool_alloter.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_ALLOTER_POOL_ALLOTER
7 | #define COMMON_ALLOTER_POOL_ALLOTER
8 |
9 | #ifdef __use_iocp__
10 | #include
11 | #endif
12 | #include
13 | #include
14 | #include "common/alloter/alloter_interface.h"
15 |
16 | namespace cppnet {
17 |
18 | static const uint32_t __default_max_bytes = 256;
19 | static const uint32_t __default_number_of_free_lists = __default_max_bytes / __align;
20 | static const uint32_t __default_number_add_nodes = 20;
21 |
22 | class PoolAlloter : public Alloter {
23 | public:
24 | PoolAlloter();
25 | ~PoolAlloter();
26 |
27 | void* Malloc(uint32_t size);
28 | void* MallocAlign(uint32_t size);
29 | void* MallocZero(uint32_t size);
30 |
31 | void Free(void* &data, uint32_t len);
32 | private:
33 | uint32_t FreeListIndex(uint32_t size, uint32_t align = __align) {
34 | return (size + align - 1) / align - 1;
35 | }
36 |
37 | void* ReFill(uint32_t size, uint32_t num = __default_number_add_nodes);
38 | void* ChunkAlloc(uint32_t size, uint32_t& nums);
39 |
40 | private:
41 | union MemNode {
42 | MemNode* _next;
43 | char _data[1];
44 | };
45 |
46 | #ifdef __use_iocp__
47 | std::mutex _mutex;
48 | #endif
49 | char* _pool_start;
50 | char* _pool_end;
51 | std::vector _free_list;
52 | std::vector _malloc_vec;
53 | std::shared_ptr _alloter;
54 | };
55 |
56 | std::shared_ptr MakePoolAlloterPtr();
57 |
58 | }
59 |
60 | #endif
--------------------------------------------------------------------------------
/common/alloter/pool_block.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include "cppnet/cppnet_config.h"
9 | #include "common/alloter/pool_block.h"
10 |
11 | namespace cppnet {
12 |
13 |
14 | BlockMemoryPool::BlockMemoryPool(uint32_t large_sz, uint32_t add_num) :
15 | _number_large_add_nodes(add_num),
16 | _large_size(large_sz) {
17 |
18 | }
19 |
20 | BlockMemoryPool::~BlockMemoryPool() {
21 | #ifdef __use_iocp__
22 | std::lock_guard lock(_mutex);
23 | #endif
24 | // free all memory
25 | for (auto iter = _free_mem_vec.begin(); iter != _free_mem_vec.end(); ++iter) {
26 | free(*iter);
27 | }
28 | _free_mem_vec.clear();
29 | }
30 |
31 | void* BlockMemoryPool::PoolLargeMalloc() {
32 | #ifdef __use_iocp__
33 | std::lock_guard lock(_mutex);
34 | #endif
35 | if (_free_mem_vec.empty()) {
36 | Expansion();
37 | }
38 |
39 | void* ret = _free_mem_vec.back();
40 | _free_mem_vec.pop_back();
41 | return ret;
42 | }
43 |
44 | void BlockMemoryPool::PoolLargeFree(void* &m) {
45 | bool release = false;
46 | {
47 | #ifdef __use_iocp__
48 | std::lock_guard lock(_mutex);
49 | #endif
50 | _free_mem_vec.push_back(m);
51 |
52 | if (_free_mem_vec.size() > __max_block_num) {
53 | release = true;
54 | }
55 | }
56 |
57 | // release some block.
58 | if (release) {
59 | ReleaseHalf();
60 | }
61 | }
62 |
63 | uint32_t BlockMemoryPool::GetSize() {
64 | #ifdef __use_iocp__
65 | std::lock_guard lock(_mutex);
66 | #endif
67 | return (uint32_t)_free_mem_vec.size();
68 | }
69 |
70 | uint32_t BlockMemoryPool::GetBlockLength() {
71 | return _large_size;
72 | }
73 |
74 | void BlockMemoryPool::ReleaseHalf() {
75 | #ifdef __use_iocp__
76 | std::lock_guard lock(_mutex);
77 | #endif
78 | size_t size = _free_mem_vec.size();
79 | size_t hale = size / 2;
80 | for (auto iter = _free_mem_vec.begin(); iter != _free_mem_vec.end();) {
81 | void* mem = *iter;
82 |
83 | iter = _free_mem_vec.erase(iter);
84 | free(mem);
85 |
86 | size--;
87 | if (iter == _free_mem_vec.end() || size <= hale) {
88 | break;
89 | }
90 | }
91 | }
92 |
93 | void BlockMemoryPool::Expansion(uint32_t num) {
94 | if (num == 0) {
95 | num = _number_large_add_nodes;
96 | }
97 |
98 | for (uint32_t i = 0; i < num; ++i) {
99 | void* mem = malloc(_large_size);
100 | // not memset!
101 | _free_mem_vec.push_back(mem);
102 | }
103 | }
104 |
105 | std::shared_ptr MakeBlockMemoryPoolPtr(uint32_t large_sz, uint32_t add_num) {
106 | return std::make_shared(large_sz, add_num);
107 | }
108 |
109 | }
--------------------------------------------------------------------------------
/common/alloter/pool_block.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_ALLOTER_POOL_BLOCK
7 | #define COMMON_ALLOTER_POOL_BLOCK
8 |
9 | #ifdef __use_iocp__
10 | #include
11 | #endif
12 | #include
13 | #include
14 | #include
15 |
16 | namespace cppnet {
17 |
18 | // all memory must return memory pool before destroy.
19 | class BlockMemoryPool {
20 | public:
21 | // bulk memory size.
22 | // every time add nodes num
23 | BlockMemoryPool(uint32_t large_sz, uint32_t add_num);
24 | virtual ~BlockMemoryPool();
25 |
26 | // for bulk memory.
27 | // return one bulk memory node
28 | virtual void* PoolLargeMalloc();
29 | virtual void PoolLargeFree(void* &m);
30 |
31 | // return bulk memory list size
32 | virtual uint32_t GetSize();
33 | // return length of bulk memory
34 | virtual uint32_t GetBlockLength();
35 |
36 | // release half memory
37 | virtual void ReleaseHalf();
38 | virtual void Expansion(uint32_t num = 0);
39 |
40 | private:
41 | #ifdef __use_iocp__
42 | std::mutex _mutex;
43 | #endif
44 | uint32_t _number_large_add_nodes; //every time add nodes num
45 | uint32_t _large_size; //bulk memory size
46 | std::vector _free_mem_vec; //free bulk memory list
47 | };
48 |
49 | std::shared_ptr MakeBlockMemoryPoolPtr(uint32_t large_sz, uint32_t add_num);
50 |
51 | }
52 |
53 | #endif
--------------------------------------------------------------------------------
/common/buffer/buffer_block.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_BUFFER_BUFFER_BLOCK
7 | #define COMMON_BUFFER_BUFFER_BLOCK
8 |
9 | #include
10 | #include "common/structure/list_slot.h"
11 | #include "common/buffer/buffer_interface.h"
12 |
13 | namespace cppnet {
14 |
15 | class BlockMemoryPool;
16 | class BufferBlock:
17 | public InnerBuffer,
18 | public ListSlot {
19 |
20 | public:
21 | BufferBlock(std::shared_ptr& alloter);
22 | ~BufferBlock();
23 |
24 | // read to res buf but don't change the read point
25 | // return read size
26 | uint32_t ReadNotMovePt(char* res, uint32_t len);
27 |
28 | uint32_t Read(std::shared_ptr buffer, uint32_t len = 0);
29 | uint32_t Write(std::shared_ptr buffer, uint32_t len = 0);
30 |
31 | uint32_t Read(char* res, uint32_t len);
32 | uint32_t Write(const char* data, uint32_t len);
33 |
34 | // clear all data
35 | void Clear();
36 |
37 | // move read point
38 | int32_t MoveReadPt(int32_t len);
39 | // move write point
40 | int32_t MoveWritePt(int32_t len);
41 |
42 | // do not read when buffer less than len.
43 | // return len when read otherwise return 0
44 | uint32_t ReadUntil(char* res, uint32_t len);
45 |
46 | // do not read when can't find specified character.
47 | // return read bytes when read otherwise return 0
48 | // when find specified character but res length is too short,
49 | // return 0 and the last param return need length
50 | uint32_t ReadUntil(char* res, uint32_t len, const char* find, uint32_t find_len, uint32_t& need_len);
51 |
52 | uint32_t GetCanWriteLength();
53 | uint32_t GetCanReadLength();
54 |
55 | // get free memory block,
56 | // res1: point to memory of start.
57 | // len1: length of memory.
58 | // there may be two blocks
59 | bool GetFreeMemoryBlock(void*& res1, uint32_t& len1, void*& res2, uint32_t& len2);
60 |
61 | // get used memory block,
62 | // res1: point to memory of start.
63 | // len1: length of memory.
64 | // there may be two blocks
65 | bool GetUseMemoryBlock(void*& res1, uint32_t& len1, void*& res2, uint32_t& len2);
66 |
67 | // return can read bytes
68 | uint32_t FindStr(const char* s, uint32_t s_len);
69 |
70 | // return block memory pool
71 | std::shared_ptr GetBlockMemoryPool();
72 |
73 | private:
74 | //find str in fix length buffer. return the first position if find otherwise return nullptr
75 | const char* _FindStrInMem(const char* buffer, const char* ch, uint32_t buffer_len, uint32_t ch_len) const;
76 | uint32_t _Read(char* res, uint32_t len, bool move_pt);
77 | uint32_t _Write(const char* data, uint32_t len);
78 |
79 | private:
80 | uint32_t _total_size; //total buffer size
81 | char* _read; //read position
82 | char* _write; //write position
83 | char* _buffer_start;
84 | char* _buffer_end;
85 | bool _can_read; //when _read == _write? Is there any data can be read.
86 | std::weak_ptr _alloter;
87 | };
88 | }
89 |
90 | #endif
--------------------------------------------------------------------------------
/common/buffer/buffer_interface.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_BUFFER_BUFFER_INTERFACE
7 | #define COMMON_BUFFER_BUFFER_INTERFACE
8 |
9 | #include
10 | #include "include/cppnet_buffer.h"
11 |
12 | namespace cppnet {
13 |
14 | class BlockMemoryPool;
15 | class InnerBuffer:
16 | public Buffer {
17 |
18 | public:
19 | InnerBuffer() {}
20 | virtual ~InnerBuffer() {}
21 |
22 | // read to res buf but don't change the read point
23 | // return read size
24 | virtual uint32_t ReadNotMovePt(char* res, uint32_t len) = 0;
25 |
26 | virtual uint32_t Read(char* res, uint32_t len) = 0;
27 | virtual uint32_t Write(const char* data, uint32_t len) = 0;
28 |
29 | // clear all data
30 | virtual void Clear() = 0;
31 |
32 | // do not read when buffer less than len.
33 | // return len when read otherwise return 0
34 | virtual uint32_t ReadUntil(char* res, uint32_t len) = 0;
35 |
36 | // do not read when can't find specified character.
37 | // return read bytes when read otherwise return 0
38 | // when find specified character but res length is too short,
39 | // return 0 and the last param return need length
40 | virtual uint32_t ReadUntil(char* res, uint32_t len, const char* find, uint32_t find_len, uint32_t& need_len) = 0;
41 |
42 | virtual uint32_t GetCanWriteLength() = 0;
43 | virtual uint32_t GetCanReadLength() = 0;
44 |
45 | // return can read bytes
46 | virtual uint32_t FindStr(const char* s, uint32_t s_len) = 0;
47 |
48 | virtual uint32_t Read(std::shared_ptr buffer, uint32_t len = 0) = 0;
49 | virtual uint32_t Write(std::shared_ptr buffer, uint32_t len = 0) = 0;
50 |
51 | // move read point
52 | virtual int32_t MoveReadPt(int32_t len) = 0;
53 | // move write point
54 | virtual int32_t MoveWritePt(int32_t len) = 0;
55 |
56 | // return block memory pool
57 | virtual std::shared_ptr GetBlockMemoryPool() = 0;
58 | };
59 |
60 | }
61 |
62 | #endif
--------------------------------------------------------------------------------
/common/buffer/buffer_queue.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_BUFFER_BUFFER_QUEUE
7 | #define COMMON_BUFFER_BUFFER_QUEUE
8 |
9 | #include
10 | #include
11 | #include "common/structure/list.h"
12 | #include "common/network/io_handle.h"
13 | #include "common/buffer/buffer_interface.h"
14 | #include "common/alloter/alloter_interface.h"
15 |
16 | namespace cppnet {
17 |
18 | class AlloterWrap;
19 | class BufferBlock;
20 | class BlockMemoryPool;
21 | class BufferQueue:
22 | public InnerBuffer {
23 | public:
24 | BufferQueue(const std::shared_ptr& block_pool,
25 | const std::shared_ptr& alloter);
26 | virtual ~BufferQueue();
27 |
28 | // read to res buf but don't change the read point
29 | // return read size
30 | virtual uint32_t ReadNotMovePt(char* res, uint32_t len);
31 |
32 | virtual uint32_t Read(std::shared_ptr buffer, uint32_t len = 0);
33 | virtual uint32_t Write(std::shared_ptr buffer, uint32_t len = 0);
34 |
35 | virtual uint32_t Read(char* res, uint32_t len);
36 | virtual uint32_t Write(const char* data, uint32_t len);
37 |
38 | // clear all data
39 | virtual void Clear();
40 |
41 | // move read point
42 | virtual int32_t MoveReadPt(int32_t len);
43 | // move write point
44 | virtual int32_t MoveWritePt(int32_t len);
45 |
46 | // do not read when buffer less than len.
47 | // return len when read otherwise return 0
48 | virtual uint32_t ReadUntil(char* res, uint32_t len);
49 |
50 | // do not read when can't find specified character.
51 | // return read bytes when read otherwise return 0
52 | // when find specified character but res length is too short,
53 | // return 0 and the last param return need length
54 | virtual uint32_t ReadUntil(char* res, uint32_t len, const char* find, uint32_t find_len, uint32_t& need_len);
55 |
56 | virtual uint32_t GetCanWriteLength();
57 | virtual uint32_t GetCanReadLength();
58 |
59 | // get free memory block,
60 | // block_vec: memory block vector.
61 | // size: count block_vec's memory, bigger than size.
62 | // if size = 0, return existing free memory block.
63 | // return size of free memory.
64 | virtual uint32_t GetFreeMemoryBlock(std::vector& block_vec, uint32_t size = 0);
65 |
66 | // get use memory block,
67 | // block_vec: memory block vector.
68 | // return size of use memory.
69 | // if size = 0, return all used memory block.
70 | virtual uint32_t GetUseMemoryBlock(std::vector& block_vec, uint32_t max_size = 0);
71 |
72 | // return can read bytes
73 | virtual uint32_t FindStr(const char* s, uint32_t s_len);
74 |
75 | // return block memory pool
76 | virtual std::shared_ptr GetBlockMemoryPool();
77 |
78 | protected:
79 | virtual void Reset();
80 | virtual void Append();
81 |
82 | protected:
83 | uint32_t _can_read_length;
84 |
85 | List _buffer_list;
86 | std::shared_ptr _buffer_write;
87 |
88 | std::shared_ptr _block_alloter;
89 | std::shared_ptr _alloter;
90 | };
91 |
92 | }
93 |
94 | #endif
--------------------------------------------------------------------------------
/common/log/base_logger.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 | // Copyright
6 |
7 | #ifndef COMMON_LOG_BASE_LOGGER_H_
8 | #define COMMON_LOG_BASE_LOGGER_H_
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | #include "common/log/log.h"
15 | #include "common/log/log_stream.h"
16 | #include "common/structure/thread_safe_queue.h"
17 |
18 | namespace cppnet {
19 |
20 | // basic management class of log printing
21 | struct Log;
22 | class Logger;
23 | class Alloter;
24 | class BaseLogger {
25 | public:
26 | BaseLogger(uint16_t cache_size, uint16_t block_size);
27 | ~BaseLogger();
28 |
29 | void SetLogger(std::shared_ptr log) { _logger = log; }
30 |
31 | void SetLevel(LogLevel level);
32 |
33 | void Debug(const char* file, uint32_t line,
34 | const char* content, va_list list);
35 | void Info(const char* file, uint32_t line,
36 | const char* content, va_list list);
37 | void Warn(const char* file, uint32_t line,
38 | const char* content, va_list list);
39 | void Error(const char* file, uint32_t line,
40 | const char* content, va_list list);
41 | void Fatal(const char* file, uint32_t line,
42 | const char* content, va_list list);
43 |
44 | LogStreamParam GetStreamParam(LogLevel level,
45 | const char* file, uint32_t line);
46 |
47 | private:
48 | std::shared_ptr GetLog();
49 | void FreeLog(Log* log);
50 | Log* NewLog();
51 |
52 | protected:
53 | uint16_t _level;
54 | uint16_t _cache_size;
55 | uint16_t _block_size;
56 |
57 | std::shared_ptr _allocter;
58 | ThreadSafeQueue _cache_queue;
59 | std::shared_ptr _logger;
60 | };
61 |
62 | } // namespace cppnet
63 |
64 | #endif // COMMON_LOG_BASE_LOGGER_H_
65 |
--------------------------------------------------------------------------------
/common/log/file_logger.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include "common/util/time.h"
9 | #include "common/log/file_logger.h"
10 |
11 | namespace cppnet {
12 |
13 | FileLogger::FileLogger(const std::string& file,
14 | FileLoggerSpiltUnit unit,
15 | uint16_t max_store_days,
16 | uint16_t time_offset):
17 | _file_name(file),
18 | _time_offset(time_offset),
19 | _spilt_unit(unit) {
20 |
21 | if (unit == FLSU_HOUR) {
22 | _time_buf_len = 13; // xxxx-xx-xx:xx
23 | _max_file_num = max_store_days * 24;
24 |
25 | } else {
26 | _time_buf_len = 10; // xxxx-xx-xx
27 | _max_file_num = max_store_days;
28 | }
29 |
30 | memset(_time, 0, __file_logger_time_buf_size);
31 |
32 | Start();
33 | }
34 |
35 | FileLogger::~FileLogger() {
36 | Stop();
37 | Join();
38 | _stream.close();
39 | }
40 |
41 | void FileLogger::Run() {
42 | while (!_stop) {
43 | auto log = Pop();
44 | if (log) {
45 | CheckTime(log->_log);
46 | if (_stream.is_open()) {
47 | _stream.write(log->_log, log->_len);
48 | _stream.put('\n');
49 | _stream.flush();
50 | }
51 |
52 | } else {
53 | break;
54 | }
55 | }
56 | }
57 |
58 | void FileLogger::Stop() {
59 | _stop = true;
60 | Push(nullptr);
61 | }
62 |
63 | void FileLogger::Debug(std::shared_ptr& log) {
64 | Push(log);
65 | Logger::Debug(log);
66 | }
67 |
68 | void FileLogger::Info(std::shared_ptr& log) {
69 | Push(log);
70 | Logger::Info(log);
71 | }
72 |
73 | void FileLogger::Warn(std::shared_ptr& log) {
74 | Push(log);
75 | Logger::Warn(log);
76 | }
77 |
78 | void FileLogger::Error(std::shared_ptr& log) {
79 | Push(log);
80 | Logger::Error(log);
81 | }
82 |
83 | void FileLogger::Fatal(std::shared_ptr& log) {
84 | Push(log);
85 | Logger::Fatal(log);
86 | }
87 |
88 | void FileLogger::SetMaxStoreDays(uint16_t max) {
89 | if (_spilt_unit == FLSU_HOUR) {
90 | _time_buf_len = 13; // xxxx-xx-xx:xx
91 | _max_file_num = max * 24;
92 |
93 | } else {
94 | _time_buf_len = 10; // xxxx-xx-xx
95 | _max_file_num = max;
96 | }
97 |
98 | CheckExpireFiles();
99 | }
100 |
101 | void FileLogger::CheckTime(char* log) {
102 | if (strncmp(_time, log + _time_offset, _time_buf_len) == 0) {
103 | return;
104 | }
105 |
106 | if (_stream.is_open()) {
107 | _stream.close();
108 | }
109 |
110 | // get new time and file name
111 | memcpy(_time, log + _time_offset, _time_buf_len);
112 | std::string file_name(_file_name);
113 | file_name.append(".");
114 | file_name.append(_time, _time_buf_len);
115 | file_name.append(".log");
116 |
117 | _history_file_names.push(file_name);
118 | CheckExpireFiles();
119 |
120 | // open new log file
121 | _stream.open(file_name.c_str(), std::ios::app | std::ios::out);
122 | }
123 |
124 | void FileLogger::CheckExpireFiles() {
125 | // delete expire files
126 | while (_history_file_names.size() > _max_file_num) {
127 | std::string del_file = _history_file_names.front();
128 | _history_file_names.pop();
129 | std::remove(del_file.c_str());
130 | }
131 | }
132 |
133 | } // namespace cppnet
134 |
--------------------------------------------------------------------------------
/common/log/file_logger.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef QUIC_COMMON_LOG_FILE_LOGGER
7 | #define QUIC_COMMON_LOG_FILE_LOGGER
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include "common/log/logger_interface.h"
14 | #include "common/thread/thread_with_queue.h"
15 |
16 | namespace cppnet {
17 |
18 | enum FileLoggerSpiltUnit {
19 | FLSU_DAY = 1,
20 | FLSU_HOUR = 2,
21 | };
22 |
23 | class FileLogger:
24 | public Logger,
25 | public ThreadWithQueue> {
26 |
27 | public:
28 | FileLogger(const std::string& file,
29 | FileLoggerSpiltUnit unit = FLSU_DAY,
30 | uint16_t max_store_days = 3,
31 | uint16_t time_offset = 5);
32 |
33 | ~FileLogger();
34 |
35 | void Run();
36 | void Stop();
37 |
38 | void Debug(std::shared_ptr& log);
39 | void Info(std::shared_ptr& log);
40 | void Warn(std::shared_ptr& log);
41 | void Error(std::shared_ptr& log);
42 | void Fatal(std::shared_ptr& log);
43 |
44 | void SetFileName(const std::string& name) { _file_name = name; }
45 | std::string GetFileName() { return _file_name; }
46 |
47 | void SetMaxStoreDays(uint16_t max);
48 | uint16_t GetMAxStorDays() { return _max_file_num; }
49 |
50 | private:
51 | void CheckTime(char* log);
52 | void CheckExpireFiles();
53 |
54 | private:
55 | enum : uint8_t {
56 | __file_logger_time_buf_size = sizeof("xxxx-xx-xx:xx")
57 | };
58 | std::string _file_name;
59 | std::fstream _stream;
60 |
61 | // for time check
62 | uint16_t _time_offset;
63 | uint8_t _time_buf_len;
64 | FileLoggerSpiltUnit _spilt_unit;
65 | char _time[__file_logger_time_buf_size];
66 |
67 | // for log file delete
68 | uint16_t _max_file_num;
69 | std::queue _history_file_names;
70 | };
71 |
72 | } // namespace cppnet
73 |
74 | #endif
75 |
--------------------------------------------------------------------------------
/common/log/log.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 |
8 | #include "common/log/log.h"
9 | #include "common/log/base_logger.h"
10 |
11 | namespace cppnet {
12 |
13 | SingletonLogger::SingletonLogger() {
14 | _logger = std::make_shared(__log_cache_size, __log_block_size);
15 | }
16 |
17 | SingletonLogger::~SingletonLogger() {
18 |
19 | }
20 |
21 | void SingletonLogger::SetLogger(std::shared_ptr log) {
22 | _logger->SetLogger(log);
23 | }
24 |
25 | void SingletonLogger::SetLevel(LogLevel level){
26 | _logger->SetLevel(level);
27 | }
28 |
29 | void SingletonLogger::Debug(const char* file, uint32_t line, const char* log...){
30 | va_list list;
31 | va_start(list, log);
32 | _logger->Debug(file, line, log, list);
33 | va_end(list);
34 | }
35 |
36 | void SingletonLogger::Info(const char* file, uint32_t line, const char* log...){
37 | va_list list;
38 | va_start(list, log);
39 | _logger->Info(file, line, log, list);
40 | va_end(list);
41 | }
42 |
43 | void SingletonLogger::Warn(const char* file, uint32_t line, const char* log...){
44 | va_list list;
45 | va_start(list, log);
46 | _logger->Warn(file, line, log, list);
47 | va_end(list);
48 | }
49 |
50 | void SingletonLogger::Error(const char* file, uint32_t line, const char* log...){
51 | va_list list;
52 | va_start(list, log);
53 | _logger->Error(file, line, log, list);
54 | va_end(list);
55 | }
56 |
57 | void SingletonLogger::Fatal(const char* file, uint32_t line, const char* log...){
58 | va_list list;
59 | va_start(list, log);
60 | _logger->Fatal(file, line, log, list);
61 | va_end(list);
62 | }
63 |
64 | LogStreamParam SingletonLogger::GetStreamParam(LogLevel level, const char* file, uint32_t line) {
65 | return _logger->GetStreamParam(level, file, line);
66 | }
67 |
68 | } // namespace cppnet
69 |
--------------------------------------------------------------------------------
/common/log/log.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef QUIC_COMMON_LOG_LOG
7 | #define QUIC_COMMON_LOG_LOG
8 |
9 | #include
10 | #include
11 |
12 | #include "common/log/log_stream.h"
13 | #include "common/util/singleton.h"
14 |
15 | namespace cppnet {
16 |
17 | // log level and switch
18 | enum LogLevel {
19 | LL_NULL = 0x00, // not print log
20 | LL_FATAL = 0x01,
21 | LL_ERROR = 0x02 | LL_FATAL,
22 | LL_WARN = 0x04 | LL_ERROR,
23 | LL_INFO = 0x08 | LL_WARN,
24 | LL_DEBUG = 0x10 | LL_INFO,
25 | };
26 |
27 | // log interface for user
28 | #define LOG_SET(log) SingletonLogger::Instance().SetLogger(log)
29 | #define LOG_SET_LEVEL(level) SingletonLogger::Instance().SetLevel(level)
30 |
31 | #define LOG_DEBUG(log, ...) SingletonLogger::Instance().Debug(__FILE__, __LINE__, log, ##__VA_ARGS__)
32 | #define LOG_INFO(log, ...) SingletonLogger::Instance().Info(__FILE__, __LINE__, log, ##__VA_ARGS__)
33 | #define LOG_WARN(log, ...) SingletonLogger::Instance().Warn(__FILE__, __LINE__, log, ##__VA_ARGS__)
34 | #define LOG_ERROR(log, ...) SingletonLogger::Instance().Error(__FILE__, __LINE__, log, ##__VA_ARGS__)
35 | #define LOG_FATAL(log, ...) SingletonLogger::Instance().Fatal(__FILE__, __LINE__, log, ##__VA_ARGS__)
36 |
37 | #define LOG_DEBUG_S LogStream(cppnet::SingletonLogger::Instance().GetStreamParam(cppnet::LL_DEBUG, __FILE__, __LINE__))
38 | #define LOG_INFO_S LogStream(cppnet::SingletonLogger::Instance().GetStreamParam(cppnet::LL_INFO, __FILE__, __LINE__))
39 | #define LOG_WARN_S LogStream(cppnet::SingletonLogger::Instance().GetStreamParam(cppnet::LL_WARN, __FILE__, __LINE__))
40 | #define LOG_ERROR_S LogStream(cppnet::SingletonLogger::Instance().GetStreamParam(cppnet::LL_ERROR, __FILE__, __LINE__))
41 | #define LOG_FATAL_S LogStream(cppnet::SingletonLogger::Instance().GetStreamParam(cppnet::LL_FATAL, __FILE__, __LINE__))
42 |
43 | // log cache config
44 | static const uint16_t __log_cache_size = 20;
45 | static const uint16_t __log_block_size = 1024;
46 |
47 |
48 | class Logger;
49 | class BaseLogger;
50 | class SingletonLogger:
51 | public Singleton {
52 |
53 | public:
54 | SingletonLogger();
55 | ~SingletonLogger();
56 |
57 | void SetLogger(std::shared_ptr log);
58 |
59 | void SetLevel(LogLevel level);
60 |
61 | // for log print as printf
62 | void Debug(const char* file, uint32_t line, const char* log...);
63 | void Info(const char* file, uint32_t line, const char* log...);
64 | void Warn(const char* file, uint32_t line, const char* log...);
65 | void Error(const char* file, uint32_t line, const char* log...);
66 | void Fatal(const char* file, uint32_t line, const char* log...);
67 |
68 | // for log stream
69 | LogStreamParam GetStreamParam(LogLevel level, const char* file, uint32_t line);
70 |
71 | private:
72 | std::shared_ptr _logger;
73 | };
74 |
75 | } // namespace cppnet
76 |
77 | #endif
--------------------------------------------------------------------------------
/common/log/log_stream.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include "common/log/log.h"
7 | #include "common/log/log_stream.h"
8 | #include "common/log/logger_interface.h"
9 |
10 | namespace cppnet {
11 |
12 | #define CHECK_CONTINUE() do{ if (!_log || _log->_len >= __log_block_size) { return *this; } } while(0);
13 |
14 | LogStream::LogStream(const LogStreamParam& param):
15 | _log(param.first),
16 | _call_back(param.second) {
17 |
18 | }
19 |
20 | LogStream::~LogStream() {
21 | if (_log && _call_back) {
22 | _call_back(_log);
23 | }
24 | }
25 |
26 | LogStream& LogStream::operator<<(bool v) {
27 | CHECK_CONTINUE()
28 |
29 | char c = v ? '1' : '0';
30 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%c", c);
31 | return *this;
32 | }
33 |
34 | LogStream& LogStream::operator<<(int8_t v) {
35 | CHECK_CONTINUE()
36 |
37 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%d", v);
38 | return *this;
39 | }
40 |
41 | LogStream& LogStream::operator<<(uint8_t v) {
42 | CHECK_CONTINUE()
43 |
44 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%u", v);
45 | return *this;
46 | }
47 |
48 | LogStream& LogStream::operator<<(int16_t v) {
49 | CHECK_CONTINUE()
50 |
51 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%d", v);
52 | return *this;
53 | }
54 |
55 | LogStream& LogStream::operator<<(uint16_t v) {
56 | CHECK_CONTINUE()
57 |
58 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%u", v);
59 | return *this;
60 | }
61 |
62 | LogStream& LogStream::operator<<(int32_t v) {
63 | CHECK_CONTINUE()
64 |
65 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%d", v);
66 | return *this;
67 | }
68 |
69 | LogStream& LogStream::operator<<(uint32_t v) {
70 | CHECK_CONTINUE()
71 |
72 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%u", v);
73 | return *this;
74 | }
75 |
76 | LogStream& LogStream::operator<<(int64_t v) {
77 | CHECK_CONTINUE()
78 | #ifdef __win__
79 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%I64d", v);
80 | #else
81 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%ld", v);
82 | #endif
83 | return *this;
84 | }
85 |
86 | LogStream& LogStream::operator<<(uint64_t v) {
87 | CHECK_CONTINUE()
88 | #ifdef __win__
89 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%I64u", v);
90 | #else
91 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%lu", v);
92 | #endif
93 | return *this;
94 | }
95 |
96 | LogStream& LogStream::operator<<(float v) {
97 | CHECK_CONTINUE()
98 |
99 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%.10lf", v);
100 | return *this;
101 | }
102 |
103 | LogStream& LogStream::operator<<(double v) {
104 | CHECK_CONTINUE()
105 |
106 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%.20lf", v);
107 | return *this;
108 | }
109 |
110 | LogStream& LogStream::operator<<(const std::string& v) {
111 | CHECK_CONTINUE()
112 |
113 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%s", v.c_str());
114 | return *this;
115 | }
116 |
117 | LogStream& LogStream::operator<<(const char* v) {
118 | CHECK_CONTINUE()
119 |
120 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%s", v);
121 | return *this;
122 | }
123 |
124 | LogStream& LogStream::operator<<(char v) {
125 | CHECK_CONTINUE()
126 |
127 | _log->_len += snprintf(_log->_log + _log->_len, __log_block_size - _log->_len, "%c", v);
128 | return *this;
129 | }
130 |
131 | } // namespace cppnet
132 |
--------------------------------------------------------------------------------
/common/log/log_stream.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef QUIC_COMMON_LOG_LOG_STREAM
7 | #define QUIC_COMMON_LOG_LOG_STREAM
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | namespace cppnet {
15 |
16 | struct Log;
17 | using LogStreamParam =
18 | std::pair, std::function)>>;
19 |
20 | class LogStream {
21 | public:
22 | LogStream(const LogStreamParam& param);
23 | ~LogStream();
24 |
25 | LogStream& Stream() { return *this; }
26 |
27 | LogStream& operator<<(bool v);
28 | LogStream& operator<<(int8_t v);
29 | LogStream& operator<<(uint8_t v);
30 | LogStream& operator<<(int16_t v);
31 | LogStream& operator<<(uint16_t v);
32 | LogStream& operator<<(int32_t v);
33 | LogStream& operator<<(uint32_t v);
34 | LogStream& operator<<(int64_t v);
35 | LogStream& operator<<(uint64_t v);
36 | LogStream& operator<<(float v);
37 | LogStream& operator<<(double v);
38 | LogStream& operator<<(const std::string& v);
39 | LogStream& operator<<(const char* v);
40 | LogStream& operator<<(char v);
41 |
42 | private:
43 | LogStream(const LogStream&) = delete;
44 | LogStream& operator=(const LogStream&) = delete;
45 |
46 | private:
47 | std::shared_ptr _log;
48 | std::function)> _call_back;
49 | };
50 |
51 | } // namespace cppnet
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/common/log/logger_interface.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef QUIC_COMMON_LOG_LOG_INTERFACE
7 | #define QUIC_COMMON_LOG_LOG_INTERFACE
8 |
9 | #include
10 | #include
11 |
12 | namespace cppnet {
13 |
14 | struct Log {
15 | char* _log;
16 | uint32_t _len;
17 | };
18 |
19 | // inherit this class to print log.
20 | // can set subclasses for different print combinations.
21 | class Logger {
22 | public:
23 | Logger() {}
24 | virtual ~Logger() {}
25 |
26 | void SetLogger(std::shared_ptr logger) { _logger = logger; }
27 | std::shared_ptr GetLogger() { return _logger; }
28 |
29 | virtual void Debug(std::shared_ptr& log) { if(_logger) _logger->Debug(log); }
30 | virtual void Info(std::shared_ptr& log) { if(_logger) _logger->Info(log); }
31 | virtual void Warn(std::shared_ptr& log) { if(_logger) _logger->Warn(log); }
32 | virtual void Error(std::shared_ptr& log) { if(_logger) _logger->Error(log); }
33 | virtual void Fatal(std::shared_ptr& log) { if(_logger) _logger->Fatal(log); }
34 |
35 | protected:
36 | std::shared_ptr _logger;
37 | };
38 |
39 | } // namespace cppnet
40 |
41 | #endif
--------------------------------------------------------------------------------
/common/log/stdout_logger.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include "common/log/stdout_logger.h"
8 |
9 | namespace cppnet {
10 |
11 | void StdoutLogger::Debug(std::shared_ptr& log) {
12 | {
13 | std::unique_lock lock(_mutex);
14 | std::cout<< log->_log << std::endl;
15 | }
16 | Logger::Debug(log);
17 | }
18 |
19 | void StdoutLogger::Info(std::shared_ptr& log) {
20 | {
21 | std::unique_lock lock(_mutex);
22 | std::cout<< log->_log << std::endl;
23 | }
24 | Logger::Info(log);
25 | }
26 |
27 | void StdoutLogger::Warn(std::shared_ptr& log) {
28 | {
29 | std::unique_lock lock(_mutex);
30 | std::cout<< log->_log << std::endl;
31 | }
32 | Logger::Warn(log);
33 | }
34 |
35 | void StdoutLogger::Error(std::shared_ptr& log) {
36 | {
37 | std::unique_lock lock(_mutex);
38 | std::cerr<< log->_log << std::endl;
39 | }
40 | Logger::Error(log);
41 | }
42 |
43 | void StdoutLogger::Fatal(std::shared_ptr& log) {
44 | {
45 | std::unique_lock lock(_mutex);
46 | std::cerr<< log->_log << std::endl;
47 | }
48 | Logger::Fatal(log);
49 | }
50 |
51 | } // namespace cppnet
52 |
--------------------------------------------------------------------------------
/common/log/stdout_logger.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef QUIC_COMMON_LOG_STDOUT_LOGGER
7 | #define QUIC_COMMON_LOG_STDOUT_LOGGER
8 |
9 | #include
10 | #include "common/log/logger_interface.h"
11 |
12 | namespace cppnet {
13 |
14 | class StdoutLogger:
15 | public Logger {
16 |
17 | public:
18 | StdoutLogger() = default;
19 | ~StdoutLogger() = default;
20 |
21 | void Debug(std::shared_ptr& log);
22 | void Info(std::shared_ptr& log);
23 | void Warn(std::shared_ptr& log);
24 | void Error(std::shared_ptr& log);
25 | void Fatal(std::shared_ptr& log);
26 |
27 | private:
28 | std::mutex _mutex;
29 | };
30 |
31 | } // namespace cppnet
32 |
33 | #endif
--------------------------------------------------------------------------------
/common/network/address.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include "common/network/address.h"
8 |
9 | namespace cppnet {
10 |
11 | Address::Address():
12 | Address(AT_IPV6) {
13 |
14 | }
15 |
16 | Address::Address(AddressType at):
17 | _address_type(at),
18 | _ip(""),
19 | _port(0) {
20 |
21 | }
22 |
23 | Address::Address(AddressType at, const std::string& ip, uint16_t port):
24 | _address_type(at),
25 | _ip(ip),
26 | _port(port) {
27 |
28 | }
29 |
30 | Address::Address(const Address& addr):
31 | _address_type(addr._address_type),
32 | _ip(addr._ip),
33 | _port(addr._port) {
34 |
35 | }
36 |
37 | Address::~Address() {
38 |
39 | }
40 |
41 | void Address::SetIp(const std::string& ip) {
42 | if (_address_type == AT_IPV6) {
43 | _ip = ToIpv6(ip);
44 |
45 | } else {
46 | _ip = ToIpv4(ip);
47 | }
48 | }
49 |
50 | const std::string Address::AsString() {
51 | if (_address_type == AT_IPV6) {
52 | return "[" + _ip + "]:" + std::to_string(_port);
53 |
54 | } else {
55 | return _ip + ":" + std::to_string(_port);
56 | }
57 | }
58 |
59 | std::ostream& operator<< (std::ostream &out, Address &addr) {
60 | const std::string str = addr.AsString();
61 | out.write(str.c_str(), str.length());
62 | return out;
63 | }
64 |
65 | bool operator==(const Address &addr1, const Address &addr2) {
66 | return addr1._ip == addr2._ip && addr1._port == addr2._port && addr1._port != 0;
67 | }
68 |
69 | bool Address::IsIpv4(const std::string& ip) {
70 | if (ip.find(':') == std::string::npos) {
71 | return true;
72 | }
73 |
74 | return false;
75 | }
76 |
77 | std::string Address::ToIpv6(const std::string& ip) {
78 | if (!IsIpv4(ip)) {
79 | return ip;
80 | }
81 |
82 | std::string ret("::FFFF:");
83 | ret.append(ip);
84 | return ret;
85 | }
86 |
87 | std::string Address::ToIpv4(const std::string& ip) {
88 | if (IsIpv4(ip)) {
89 | return ip;
90 | }
91 | std::size_t pos = ip.rfind(':');
92 |
93 | return std::string(&ip[pos], ip.length() - pos);
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/common/network/address.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_NETWORK_ADDRESS
7 | #define COMMON_NETWORK_ADDRESS
8 |
9 | #include
10 | #include
11 |
12 | namespace cppnet {
13 |
14 | enum AddressType {
15 | AT_IPV4 = 0x1,
16 | AT_IPV6 = 0x2,
17 | };
18 |
19 | class Address {
20 | public:
21 | Address();
22 | Address(AddressType at);
23 | Address(AddressType at, const std::string& ip, uint16_t port);
24 | Address(const Address& addr);
25 | ~Address();
26 |
27 | void SetType(AddressType at) { _address_type = at; }
28 | AddressType GetType() { return _address_type; }
29 |
30 | void SetIp(const std::string& ip);
31 | const std::string& GetIp() { return _ip; }
32 |
33 | void SetAddrPort(uint16_t port) { _port = port; }
34 | uint16_t GetAddrPort() { return _port; }
35 |
36 | const std::string AsString();
37 |
38 | friend std::ostream& operator<< (std::ostream &out, Address &addr);
39 | friend bool operator==(const Address &addr1, const Address &addr2);
40 |
41 | static bool IsIpv4(const std::string& ip);
42 |
43 | private:
44 | std::string ToIpv6(const std::string& ip);
45 | std::string ToIpv4(const std::string& ip);
46 |
47 | protected:
48 | AddressType _address_type;
49 | std::string _ip;
50 | uint16_t _port;
51 | };
52 |
53 | }
54 |
55 | #endif
--------------------------------------------------------------------------------
/common/network/io_handle.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_NETWORK_IO_HANDLE
7 | #define COMMON_NETWORK_IO_HANDLE
8 |
9 | #include
10 | #include "common/util/os_return.h"
11 | #include "common/network/address.h"
12 |
13 | namespace cppnet {
14 |
15 | struct Iovec {
16 | #ifdef __win__
17 | size_t _iov_len; // size of buffer
18 | void* _iov_base; // starting address of buffer
19 | #else
20 | void* _iov_base; // starting address of buffer
21 | size_t _iov_len; // size of buffer
22 | #endif
23 | Iovec(void* base, size_t len): _iov_base(base), _iov_len(len) {}
24 | };
25 |
26 | class OsHandle {
27 | public:
28 | static SysCallInt64Result TcpSocket(bool ipv4 = false);
29 |
30 | static SysCallInt32Result Bind(int64_t sockfd, Address& addr);
31 |
32 | static SysCallInt32Result Listen(int64_t sockfd, uint32_t len = 0);
33 |
34 | static SysCallInt32Result Connect(int64_t sockfd, Address& addr);
35 |
36 | static SysCallInt32Result Close(int64_t sockfd);
37 |
38 | static SysCallInt64Result Accept(int64_t sockfd, Address& address);
39 |
40 | static SysCallInt32Result Write(int64_t sockfd, const char *data, uint32_t len);
41 | static SysCallInt32Result Writev(int64_t sockfd, Iovec *vec, uint32_t vec_len);
42 |
43 | static SysCallInt32Result Recv(int64_t sockfd, char *data, uint32_t len, uint16_t flag);
44 | static SysCallInt32Result Readv(int64_t sockfd, Iovec *vec, uint32_t vec_len);
45 |
46 | };
47 |
48 | }
49 |
50 | #endif
--------------------------------------------------------------------------------
/common/network/posix/socket.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include "common/network/socket.h"
12 |
13 | namespace cppnet {
14 |
15 | int32_t SocketNoblocking(uint64_t sock) {
16 | int32_t old_option = fcntl(sock, F_GETFL);
17 | int32_t new_option = old_option | O_NONBLOCK;
18 | fcntl(sock, F_SETFL, new_option);
19 | return old_option;
20 | }
21 |
22 | int32_t ReusePort(uint64_t sock) {
23 | int32_t opt = 1;
24 | int32_t ret = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT,
25 | &opt, static_cast(sizeof(opt)));
26 | return ret;
27 | }
28 |
29 | bool CheckConnect(const uint64_t sock) {
30 | /*struct pollfd fd;
31 | int32_t ret = 0;
32 | socklen_t len = 0;
33 | fd.fd = sock;
34 | fd.events = POLLOUT;
35 | if (poll(&fd, 1, 20000) == -1) {
36 | if(errno != EINTR){
37 | return false;
38 | }
39 | }*/
40 | int32_t ret = 0;
41 | socklen_t len = sizeof(ret);
42 | if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &ret, &len) == -1) {
43 | return false;
44 | }
45 | if(ret != 0) {
46 | return false;
47 | }
48 | return true;
49 | }
50 |
51 |
52 | }
--------------------------------------------------------------------------------
/common/network/socket.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_NETWORK_SOCKET
7 | #define COMMON_NETWORK_SOCKET
8 |
9 | #include
10 |
11 | namespace cppnet {
12 |
13 | int32_t SocketNoblocking(uint64_t sock);
14 |
15 | int32_t ReusePort(uint64_t sock);
16 |
17 | // check socket connect
18 | bool CheckConnect(const uint64_t sock);
19 |
20 | }
21 | #endif
22 |
--------------------------------------------------------------------------------
/common/network/win/socket.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include "common/network/socket.h"
9 |
10 | namespace cppnet {
11 |
12 | int32_t SocketNoblocking(uint64_t sock) {
13 | unsigned long ul = 1;
14 | return ioctlsocket(sock, FIONBIO, (unsigned long *)&ul);
15 | }
16 |
17 | int32_t ReusePort(uint64_t sock) {
18 | int32_t opt = 1;
19 | return setsockopt((SOCKET)sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
20 | }
21 |
22 | bool CheckConnect(const uint64_t sock) {
23 | int32_t seconds;
24 | int32_t bytes = sizeof(seconds);
25 | int32_t iResult = 0;
26 |
27 | iResult = getsockopt(sock, SOL_SOCKET, SO_CONNECT_TIME, (char*)&seconds, (PINT)&bytes);
28 | if (iResult != NO_ERROR) {
29 | return false;
30 |
31 | } else {
32 | if (seconds == 0xFFFFFFFF) {
33 | return false;
34 | }
35 | }
36 | return true;
37 | }
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/common/os/convert.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_OS_CONVERT
7 | #define COMMON_OS_CONVERT
8 |
9 | #include
10 |
11 | namespace cppnet {
12 |
13 | void Localtime(const uint64_t* time, void* out_tm);
14 |
15 | char* ErrnoInfo(uint32_t err);
16 |
17 | }
18 |
19 | #endif
--------------------------------------------------------------------------------
/common/os/os_info.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include "common/os/os_info.h"
8 |
9 | uint32_t cppnet::GetCpuNum() {
10 | return std::thread::hardware_concurrency();
11 | }
--------------------------------------------------------------------------------
/common/os/os_info.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_OS_OS_INFO
7 | #define COMMON_OS_OS_INFO
8 |
9 | #include
10 |
11 | namespace cppnet {
12 |
13 | uint32_t GetCpuNum();
14 |
15 | }
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/common/os/posix/convert.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include "common/os/convert.h"
9 |
10 | namespace cppnet {
11 |
12 | void Localtime(const uint64_t* time, void* out_tm) {
13 | ::localtime_r((time_t*)time, (tm*)out_tm);
14 | }
15 |
16 | char* ErrnoInfo(uint32_t err) {
17 | return strerror(err);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/common/os/win/convert.cpp:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #include
7 | #include
8 | #include "common/os/convert.h"
9 |
10 | namespace cppnet {
11 |
12 | void Localtime(const uint64_t* time, void* out_tm) {
13 | localtime_s((tm*)out_tm, (time_t*)time);
14 | }
15 |
16 | char* ErrnoInfo(uint32_t err) {
17 | LPVOID hlocal = NULL;
18 | ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL
19 | , err, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR)&hlocal, 0, NULL);
20 |
21 | return (char*)hlocal;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/common/structure/list.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_STRUCTURE_LIST
7 | #define COMMON_STRUCTURE_LIST
8 |
9 | #include
10 | #include
11 | #include "common/structure/list_slot.h"
12 |
13 | namespace cppnet {
14 |
15 | template
16 | class List {
17 | public:
18 | List(): _size(0) {}
19 | ~List() {}
20 |
21 | uint32_t Size() { return _size; }
22 |
23 | std::shared_ptr GetHead() { return _head; }
24 | std::shared_ptr GetTail() { return _tail; }
25 |
26 | void Clear() {
27 | _size = 0;
28 |
29 | _head.reset();
30 | _tail.reset();
31 | }
32 |
33 | void PushBack(std::shared_ptr v) {
34 | if (!v) {
35 | return;
36 | }
37 |
38 | if (!_tail) {
39 | _tail = v;
40 | _head = v;
41 |
42 | } else {
43 | _tail->SetNext(v);
44 | v->SetPrev(_tail);
45 | _tail = v;
46 | }
47 | _size++;
48 | }
49 |
50 | std::shared_ptr PopBack() {
51 | if (!_tail) {
52 | return nullptr;
53 | }
54 |
55 | auto ret = _tail;
56 | _tail = _tail->GetPrev();
57 | if (!_tail) {
58 | _head.reset();
59 |
60 | } else {
61 | _tail->SetNext(nullptr);
62 | }
63 | _size--;
64 |
65 | return ret;
66 | }
67 |
68 | void PushFront(std::shared_ptr v) {
69 | if (!v) {
70 | return;
71 | }
72 |
73 | if (!_head) {
74 | _tail = v;
75 | _head = v;
76 |
77 | } else {
78 | _head->SetPrev(v);
79 | v->SetNext(_head);
80 | _head = v;
81 | }
82 | _size++;
83 | }
84 |
85 | std::shared_ptr PopFront() {
86 | if (!_head) {
87 | return nullptr;
88 | }
89 |
90 | auto ret = _head;
91 | _head = _head->GetNext();
92 | if (!_head) {
93 | _tail.reset();
94 | }
95 |
96 | _size--;
97 |
98 | return ret;
99 | }
100 |
101 | private:
102 | uint32_t _size;
103 | std::shared_ptr _head;
104 | std::shared_ptr _tail;
105 | };
106 |
107 | }
108 |
109 | #endif
--------------------------------------------------------------------------------
/common/structure/list_slot.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_STRUCTURE_LIST_SLOT
7 | #define COMMON_STRUCTURE_LIST_SLOT
8 |
9 | #include
10 |
11 | namespace cppnet {
12 |
13 | template
14 | class ListSlot {
15 | public:
16 | ListSlot() {}
17 | virtual ~ListSlot() {}
18 |
19 | void SetNext(std::shared_ptr v) { _next = v; }
20 | std::shared_ptr GetNext() { return _next; }
21 |
22 | void SetPrev(std::shared_ptr v) { _prev = v; }
23 | std::shared_ptr GetPrev() { return _prev.lock(); }
24 |
25 | protected:
26 | std::weak_ptr _prev;
27 | std::shared_ptr _next;
28 | };
29 |
30 | }
31 |
32 | #endif
--------------------------------------------------------------------------------
/common/structure/thread_safe_block_queue.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_STRUCTURE_THREAD_SAFE_BLOCK_QUEUE
7 | #define COMMON_STRUCTURE_THREAD_SAFE_BLOCK_QUEUE
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | namespace cppnet {
14 |
15 | template
16 | class ThreadSafeBlockQueue {
17 | public:
18 | ThreadSafeBlockQueue() {}
19 | ~ThreadSafeBlockQueue() {}
20 |
21 | void Push(const T& element) {
22 | std::lock_guard lock(_mutex);
23 | _queue.push(element);
24 | _empty_notify.notify_one();
25 | }
26 |
27 | T Pop() {
28 | std::unique_lock lock(_mutex);
29 | _empty_notify.wait(_mutex, [this]() {return !this->_queue.empty(); });
30 |
31 | auto ret = std::move(_queue.front());
32 | _queue.pop();
33 |
34 | return ret;
35 | }
36 |
37 | void Clear() {
38 | std::lock_guard lock(_mutex);
39 | while (!_queue.empty()) {
40 | _queue.pop();
41 | }
42 | }
43 |
44 | uint32_t Size() {
45 | std::lock_guard lock(_mutex);
46 | return _queue.size();
47 | }
48 |
49 | bool Empty() {
50 | std::lock_guard lock(_mutex);
51 | return _queue.empty();
52 | }
53 |
54 | private:
55 | std::mutex _mutex;
56 | std::queue _queue;
57 | std::condition_variable_any _empty_notify;
58 | };
59 |
60 | }
61 | #endif
--------------------------------------------------------------------------------
/common/structure/thread_safe_queue.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_STRUCTURE_THREAD_SAFE_QUEUE
7 | #define COMMON_STRUCTURE_THREAD_SAFE_QUEUE
8 |
9 | #include
10 | #include
11 |
12 | namespace cppnet {
13 |
14 | template
15 | class ThreadSafeQueue {
16 | public:
17 | ThreadSafeQueue() {}
18 | ~ThreadSafeQueue() {}
19 |
20 | void Push(const T& element) {
21 | std::unique_lock lock(_mutex);
22 | _queue.push(element);
23 | }
24 |
25 | bool Pop(T& value) {
26 | std::unique_lock lock(_mutex);
27 | if (_queue.empty()) {
28 | return false;
29 | }
30 | value = std::move(_queue.front());
31 | _queue.pop();
32 | return true;
33 | }
34 |
35 | void Clear() {
36 | std::unique_lock lock(_mutex);
37 | while (!_queue.empty()) {
38 | _queue.pop();
39 | }
40 | }
41 |
42 | size_t Size() {
43 | std::unique_lock lock(_mutex);
44 | return _queue.size();
45 | }
46 |
47 | bool Empty() {
48 | std::unique_lock lock(_mutex);
49 | return _queue.empty();
50 | }
51 |
52 | private:
53 | std::mutex _mutex;
54 | std::queue _queue;
55 | };
56 |
57 | }
58 |
59 | #endif
--------------------------------------------------------------------------------
/common/structure/thread_safe_unordered_map.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_STRUCTURE_THREAD_SAFE_QUEUE
7 | #define COMMON_STRUCTURE_THREAD_SAFE_QUEUE
8 |
9 | #include
10 | #include
11 |
12 | namespace cppnet {
13 |
14 | template
15 | class ThreadSafeUnorderedMap {
16 | public:
17 | ThreadSafeUnorderedMap() {}
18 | ~ThreadSafeUnorderedMap() {}
19 |
20 | V& operator[] (const K& key) {
21 | std::lock_guard lock(_mutex);
22 | return _unordered_map[key];
23 | }
24 |
25 | bool Find(const K& key) {
26 | std::lock_guard lock(_mutex);
27 | return _unordered_map.find(key) != _unordered_map.end();
28 | }
29 |
30 | void Insert(const std::pair& item) {
31 | std::lock_guard lock(_mutex);
32 | _unordered_map.insert(item);
33 | }
34 |
35 | void Erase(const K& key) {
36 | std::lock_guard lock(_mutex);
37 | _unordered_map.erase(key);
38 | }
39 |
40 | void Clear() {
41 | std::lock_guard lock(_mutex);
42 | _unordered_map.clear();
43 | }
44 |
45 | size_t Size() {
46 | std::lock_guard lock(_mutex);
47 | return _unordered_map.size();
48 | }
49 |
50 | bool Empty() {
51 | std::lock_guard lock(_mutex);
52 | return _unordered_map.empty();
53 | }
54 |
55 | std::unordered_map& GetMap() {
56 | return _unordered_map;
57 | }
58 |
59 | private:
60 | std::unordered_map _unordered_map;
61 | std::mutex _mutex;
62 | };
63 |
64 | }
65 |
66 | #endif
--------------------------------------------------------------------------------
/common/thread/thread.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_THREAD_THREAD
7 | #define COMMON_THREAD_THREAD
8 |
9 | #include // about thread
10 | #include // for atomic_bool
11 | #include // for shared_ptr
12 | #include // for bind
13 |
14 | namespace cppnet {
15 |
16 | class Thread {
17 | public:
18 | Thread(): _stop(true) {}
19 | virtual ~Thread() {}
20 |
21 | //base option
22 | virtual void Start() {
23 | _stop = false;
24 | if (!_thread) {
25 | _thread = std::unique_ptr(new std::thread(std::bind(&Thread::Run, this)));
26 | }
27 | }
28 |
29 | virtual void Stop() {
30 | _stop = true;
31 | }
32 |
33 | virtual void Join() {
34 | if (_thread && _thread->joinable()) {
35 | _thread->join();
36 | }
37 | }
38 | //TO DO
39 | virtual void Run() = 0;
40 |
41 | virtual bool IsStop() {
42 | return _stop;
43 | }
44 |
45 | protected:
46 | Thread(const Thread&) = delete;
47 | Thread& operator=(const Thread&) = delete;
48 |
49 | protected:
50 | std::atomic_bool _stop;
51 | std::unique_ptr _thread;
52 | };
53 |
54 | }
55 | #endif
--------------------------------------------------------------------------------
/common/thread/thread_with_queue.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_THREAD_THREAD_WITH_QUEUE
7 | #define COMMON_THREAD_THREAD_WITH_QUEUE
8 |
9 | #include "common/thread/thread.h"
10 | #include "common/structure/thread_safe_block_queue.h"
11 |
12 | namespace cppnet {
13 |
14 | template
15 | class ThreadWithQueue:
16 | public Thread {
17 |
18 | public:
19 | ThreadWithQueue() {}
20 | virtual ~ThreadWithQueue() {}
21 |
22 | uint32_t GetQueueSize() {
23 | return _queue.Size();
24 | }
25 |
26 | void Push(const T& t) {
27 | _queue.Push(t);
28 | }
29 |
30 | T Pop() {
31 | return std::move(_queue.Pop());
32 | }
33 |
34 | //TO DO
35 | virtual void Run() = 0;
36 |
37 | protected:
38 | ThreadWithQueue(const ThreadWithQueue&) = delete;
39 | ThreadWithQueue& operator=(const ThreadWithQueue&) = delete;
40 |
41 | private:
42 | ThreadSafeBlockQueue _queue;
43 | };
44 |
45 | }
46 | #endif
--------------------------------------------------------------------------------
/common/timer/timer.cpp:
--------------------------------------------------------------------------------
1 |
2 | // Use of this source code is governed by a BSD 3-Clause License
3 | // that can be found in the LICENSE file.
4 |
5 | // Author: caozhiyi (caozhiyi5@gmail.com)
6 |
7 | #include "common/timer/timer.h"
8 | #include "common/timer/timer_container.h"
9 |
10 | namespace cppnet {
11 |
12 | std::shared_ptr MakeTimer1Sec() {
13 | return std::make_shared(nullptr, TU_MILLISECOND, TU_SECOND);
14 | }
15 |
16 | std::shared_ptr MakeTimer1Min() {
17 | auto sec_sub = std::make_shared(nullptr, TU_MILLISECOND, TU_SECOND);
18 | auto timer = std::make_shared(sec_sub, TU_SECOND, TU_MINUTE);
19 | sec_sub->SetRootTimer(timer);
20 | return timer;
21 | }
22 |
23 | std::shared_ptr MakeTimer1Hour() {
24 | auto sec_sub = std::make_shared(nullptr, TU_MILLISECOND, TU_SECOND);
25 | auto min_sub = std::make_shared(sec_sub, TU_SECOND, TU_MINUTE);
26 | auto timer = std::make_shared(min_sub, TU_MINUTE, TU_HOUR);
27 | sec_sub->SetRootTimer(timer);
28 | min_sub->SetRootTimer(timer);
29 |
30 | return timer;
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/common/timer/timer.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_TIMER_TIMER
7 | #define COMMON_TIMER_TIMER
8 |
9 | #include
10 | #include "common/timer/timer_interface.h"
11 |
12 | namespace cppnet {
13 |
14 | std::shared_ptr MakeTimer1Sec();
15 |
16 | std::shared_ptr MakeTimer1Min();
17 |
18 | std::shared_ptr MakeTimer1Hour();
19 |
20 | }
21 |
22 | #endif
--------------------------------------------------------------------------------
/common/timer/timer_container.h:
--------------------------------------------------------------------------------
1 | // Use of this source code is governed by a BSD 3-Clause License
2 | // that can be found in the LICENSE file.
3 |
4 | // Author: caozhiyi (caozhiyi5@gmail.com)
5 |
6 | #ifndef COMMON_TIMER_TIMER_CONTAINER
7 | #define COMMON_TIMER_TIMER_CONTAINER
8 |
9 | #include