├── BLADE_ROOT ├── Makefile ├── README.md ├── base ├── BUILD ├── addr2line.h ├── addr_map.h ├── auto_var.h ├── base64.h ├── bind_this.h ├── bind_this_mgr.h ├── bobhash.h ├── closure.h ├── cpu_affinity.h ├── defer.h ├── delay_init.h ├── fd_queue.h ├── fifo.h ├── fifo_lockfree.h ├── fixed_mempool.h ├── gcc_builtin_help.h ├── hash_table_base.h ├── hashtable_lockfree.h ├── http_parser.h ├── int_map.h ├── ip_list.h ├── json_to.h ├── lifo.h ├── lifo_lockfree.h ├── list.h ├── llist.h ├── log_format.h ├── lua_base.h ├── lua_bind.h ├── macro_help.h ├── module.h ├── murmurhash3.h ├── net_tool.h ├── obj_pool.h ├── pb2json.h ├── pb2sqlite.h ├── pb_obj_pool.h ├── pbc.h ├── plog.h ├── ptr_cast.h ├── query_string.h ├── random.h ├── redis_parse.h ├── ref_str.h ├── ref_str_tool.h ├── rotate_log.h ├── scope_lock.h ├── scoped_ptr.h ├── src │ ├── addr2line.cpp │ ├── base64.cpp │ ├── bind_this_jump.s │ ├── bind_this_mgr.cpp │ ├── bobhash.cpp │ ├── cpu_affinity.cpp │ ├── delay_init.cpp │ ├── ebpf.c │ ├── fd_queue.cpp │ ├── fixed_mempool.cpp │ ├── http_parser.rl │ ├── module.cpp │ ├── murmurhash3.cpp │ ├── net_tool.cpp │ ├── pb2json.cpp │ ├── pb2sqlite.cpp │ ├── pb_obj_pool.cpp │ ├── pbc.cpp │ ├── plog.cpp │ ├── query_string.rl │ ├── random.cpp │ ├── redis_parse.rl │ ├── sigsegv.cpp │ ├── time_helper.cpp │ ├── tls.cpp │ ├── to_lua_mgr.cpp │ ├── unix_socket_send_fd.cpp │ └── url_encode.cpp ├── str_map.h ├── string2number.h ├── string_builder.h ├── string_tpl.h ├── struct2.h ├── test │ ├── bind_this_test.cpp │ ├── closure_test.cpp │ ├── defer_test.cpp │ ├── http_parser_test.cpp │ ├── json_to_test.cpp │ ├── module_a.cpp │ ├── module_b.cpp │ ├── module_test.cpp │ ├── pb2sqlite_test.cpp │ ├── plog_test.cpp │ ├── ptr_cast_test.cpp │ ├── query_string_test.cpp │ ├── string_tpl_test.cpp │ ├── test.proto │ ├── time_helper_test.cpp │ ├── tls_bench.cpp │ ├── to_json_test.cpp │ ├── to_xml_test.cpp │ └── url_encode_test.cpp ├── time_helper.h ├── tls.h ├── to_json.h ├── to_lua_mgr.h ├── to_xml.h ├── unix_socket_send_fd.h └── url_encode.h ├── build_all.sh ├── clang_env.sh ├── code_summary.sh ├── core ├── BUILD ├── co_pool.h ├── common.h ├── conet_all.h ├── coroutine.h ├── coroutine_env.h ├── dispatch.h ├── event_notify.h ├── fcontext.h ├── fd_ctx.h ├── gc.h ├── hook_helper.h ├── log.h ├── network_hook.h ├── parallel.h ├── pthread_hook.h ├── src │ ├── ares_wrap.cpp │ ├── ares_wrap.h │ ├── co_pool.cpp │ ├── co_swap_test.cpp │ ├── common.cpp │ ├── coroutine.cpp │ ├── coroutine_env.cpp │ ├── disk_io_hook.cpp │ ├── dispatch.cpp │ ├── fd_ctx.cpp │ ├── gc.cpp │ ├── gethostbyname_test.cpp │ ├── jump_x86_64_sysv_elf_gas.s │ ├── make_x86_64_sysv_elf_gas.s │ ├── malloc_hook.cpp │ ├── network.cpp │ ├── network_hook.cpp │ ├── network_safe.cpp │ ├── pthread_hook.cpp │ ├── stacktrace.cpp │ ├── swap_context.s │ ├── time_hook.cpp │ ├── time_mgr.cpp │ ├── timewheel.cpp │ ├── version.cpp │ └── wait_queue.cpp ├── static_var.h ├── time_mgr.h ├── timewheel.h ├── wait_id_event.h └── wait_queue.h ├── example ├── BUILD ├── aio_test.cpp ├── echo_cli.cpp ├── echo_cli_co.cpp ├── echo_cli_co_async.cpp ├── echo_rpc.proto ├── echo_rpc_cli.cpp ├── echo_rpc_cli_co.cpp ├── echo_rpc_cli_co2.cpp ├── echo_rpc_cli_duplex.cpp ├── echo_rpc_cli_duplex2.cpp ├── echo_rpc_cli_udp.cpp ├── echo_rpc_server.cpp ├── echo_server.cpp ├── echo_server_async.cpp ├── http_bench.sh ├── http_server.cpp ├── pkv.cpp ├── sigsegv.cpp └── tsung.xml ├── gcc_env.sh ├── get_deps.sh ├── qjs ├── BUILD ├── Changelog ├── LICENSE ├── Makefile ├── cutils.c ├── cutils.h ├── doc │ ├── jsbignum.texi │ └── quickjs.texi ├── examples │ ├── fib.c │ ├── fib_module.js │ ├── hello.js │ ├── hello_module.js │ ├── pi_bigdecimal.js │ ├── pi_bigfloat.js │ ├── pi_bigint.js │ ├── point.c │ ├── test_fib.js │ └── test_point.js ├── libbf.c ├── libbf.h ├── libregexp-opcode.h ├── libregexp.c ├── libregexp.h ├── libunicode-table.h ├── libunicode.c ├── libunicode.h ├── list.h ├── qjs.c ├── qjsc.c ├── qjscalc.js ├── quickjs-atom.h ├── quickjs-libc.c ├── quickjs-libc.h ├── quickjs-opcode.h ├── quickjs.c ├── quickjs.h ├── readme.txt ├── repl.js ├── run-test262.c ├── test262.conf ├── test262_errors.txt ├── test262o.conf ├── test262o_errors.txt ├── tests │ ├── bjson.c │ ├── microbench.js │ ├── test262.patch │ ├── test_bignum.js │ ├── test_bjson.js │ ├── test_builtin.js │ ├── test_closure.js │ ├── test_language.js │ ├── test_loop.js │ ├── test_op_overloading.js │ ├── test_qjscalc.js │ ├── test_std.js │ ├── test_worker.js │ └── test_worker_module.js ├── unicode_download.sh ├── unicode_gen.c └── unicode_gen_def.h ├── svrkit ├── BUILD ├── channel.h ├── cmd_base.h ├── conn_info.h ├── default_server.conf ├── http_server.h ├── load_balance.h ├── rpc_base_pb.proto ├── rpc_client_stub.h ├── rpc_conf.proto ├── rpc_pb_client.h ├── rpc_pb_client_duplex.h ├── rpc_pb_server.h ├── rpc_pb_server_base.h ├── rpc_pb_server_base_impl.h ├── server_base.h ├── server_builder.h ├── server_common.h ├── src │ ├── channel.cpp │ ├── http_server.cpp │ ├── rpc_base_pb_test.cpp │ ├── rpc_base_test.cpp │ ├── rpc_cmd_base.cpp │ ├── rpc_pb_client.cpp │ ├── rpc_pb_client_duplex.cpp │ ├── rpc_pb_server.cpp │ ├── rpc_pb_server_base.cpp │ ├── server_builder.cpp │ ├── server_common.cpp │ ├── server_main.cpp │ ├── stat_mgr.cpp │ ├── tcp_server.cpp │ └── udp_server.cpp ├── stat_mgr.h ├── static │ ├── bootstrap-theme.min.css │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── form.html │ ├── jquery.js │ ├── list.html │ ├── qrcode.min.js │ ├── semantic.min.css │ └── semantic.min.js ├── tcp_server.h └── udp_server.h └── tools ├── callviz.py ├── code_stats.sh └── cpplint.py /BLADE_ROOT: -------------------------------------------------------------------------------- 1 | cc_config( 2 | extra_incs=['thirdparty/protobuf/', 'thirdparty/'], 3 | cflags=['-m64', '-march=native'], 4 | cxxflags=['-std=c++2a', '-m64', '-march=native', '-Dtypeof=__typeof__', '-fno-exceptions'], 5 | optimize=['-O3'], #'fprofile-generate=/data/profile/'], 6 | linkflags=['-flto', #'-lgcov', '--coverage' 7 | ], 8 | ) -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: base core svrkit example 2 | 3 | base: 4 | (cd base; blade build) 5 | 6 | core: 7 | (cd core; blade build) 8 | 9 | svrkit: 10 | (cd svrkit; blade build) 11 | 12 | example: 13 | (cd example; blade build) 14 | 15 | .PHONY: all base core svrkit example 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # conet 2 | write simple linux network server and run it in parallel 3 | # TODO 4 | change to c++0x11 5 | -------------------------------------------------------------------------------- /base/addr2line.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: addr2line.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月05日 14时17分14秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_ADDR2LINE_H__ 19 | #define __CONET_ADDR2LINE_H__ 20 | namespace conet 21 | { 22 | 23 | int addr2line (void *addr, char * func_name, int func_len, char *file_name, int file_len, int *line); 24 | 25 | } 26 | 27 | 28 | #endif /* end of include guard */ 29 | -------------------------------------------------------------------------------- /base/addr_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: addr_map.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月27日 15时22分03秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_ADDR_MAP_H__ 19 | #define __CONET_ADDR_MAP_H__ 20 | 21 | #include "hash_table_base.h" 22 | 23 | namespace conet 24 | { 25 | 26 | 27 | class AddrMap : public HashTableBase 28 | { 29 | public: 30 | 31 | static 32 | inline 33 | uint64_t hash_code(void* addr) 34 | { 35 | return (uint64_t)(addr) * 2654435761; 36 | } 37 | 38 | static inline 39 | bool equal(void *l, void *r) 40 | { 41 | return l == r; 42 | } 43 | 44 | }; 45 | 46 | } 47 | 48 | 49 | #endif /* end of include guard */ 50 | -------------------------------------------------------------------------------- /base/auto_var.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * ===================================================================================== 4 | * 5 | * Filename: auto_var.h 6 | * 7 | * Description: 8 | * 9 | * Version: 1.0 10 | * Created: 20111ʱ35ST 11 | * Revision: none 12 | * Compiler: gcc 13 | * 14 | * Author: piboye 15 | * Company: 16 | * 17 | * ===================================================================================== 18 | */ 19 | 20 | #ifndef AUTO_VAR_INC 21 | #define AUTO_VAR_INC 22 | 23 | #define AUTO_VAR(name, op, value) typeof(value) name op (value) 24 | #define AUTO_REF_VAR(name, op, value) typeof(value) & name op (value) 25 | 26 | #endif /* ----- #ifndef AUTO_VAR_INC ----- */ 27 | -------------------------------------------------------------------------------- /base/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_H_VXIK8QOG 2 | #define BASE64_H_VXIK8QOG 3 | 4 | #include 5 | #include 6 | 7 | namespace conet 8 | { 9 | int base64_encode(char const * str, int len, char * dest); 10 | int base64_decode(char const * str, int len, char * dest); 11 | } 12 | 13 | #endif /* end of include guard: BASE64_H_VXIK8QOG */ 14 | -------------------------------------------------------------------------------- /base/bind_this.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: bind_this.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年01月13日 15时41分17秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_BIND_THIS_H__ 19 | #define __CONET_BIND_THIS_H__ 20 | #include "bind_this_mgr.h" 21 | #include "list.h" 22 | #include 23 | #include 24 | #include "macro_help.h" 25 | 26 | namespace conet 27 | { 28 | 29 | template 30 | inline 31 | R (*get_bind_this_wrap_helper( R (ClassT::*f)() ))() 32 | { 33 | struct Wrap 34 | { 35 | static R run() 36 | { 37 | void * self=NULL; 38 | R (* func)(void *)=NULL; 39 | asm("movq %%r10, %0" :"=r"(self)::); 40 | asm("movq %%r11, %0" :"=r"(func)::); 41 | return func(self); 42 | } 43 | }; 44 | return &Wrap::run; 45 | } 46 | 47 | #define CONET_MAX_BIND_THIS_PARAM_NUM 20 48 | 49 | #define CONET_GET_BIND_THIS_WRAP_HELPER_IMPL(z, n, t) \ 50 | template \ 51 | inline \ 52 | R (*get_bind_this_wrap_helper(R (ClassT::*f)(BOOST_PP_ENUM_PARAMS(n, arg_type_)))) \ 53 | (BOOST_PP_ENUM_PARAMS(n, arg_type_)) \ 54 | { \ 55 | struct Wrap \ 56 | { \ 57 | static R run( BOOST_PP_REPEAT(n, CONET_ARG_DEF, d) ) \ 58 | { \ 59 | void * self=NULL; \ 60 | R (* func)(void *, BOOST_PP_ENUM_PARAMS(n, arg_type_)) = NULL; \ 61 | asm("movq %%r10, %0" :"=r"(self)::); \ 62 | asm("movq %%r11, %0" :"=r"(func)::); \ 63 | return func(self, BOOST_PP_ENUM_PARAMS(n, arg)); \ 64 | } \ 65 | }; \ 66 | return &Wrap::run; \ 67 | } 68 | 69 | 70 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(CONET_MAX_BIND_THIS_PARAM_NUM), CONET_GET_BIND_THIS_WRAP_HELPER_IMPL, t) 71 | 72 | 73 | #define BindThis(obj, func) \ 74 | ({ \ 75 | conet::BindThisData *d = conet::get_bind_this_data(); \ 76 | d->jump_func = (uint64_t)(conet::get_bind_this_wrap_helper(&func)); \ 77 | d->self = (uint64_t )(&obj); \ 78 | typeof(&func) pfn = &func; \ 79 | memcpy(&d->mem_func, (void const *)(&pfn), sizeof(uint64_t)); \ 80 | (typeof(conet::get_bind_this_wrap_helper(&func))) (&(d->code)); \ 81 | }) 82 | 83 | } 84 | 85 | #endif /* end of include guard */ 86 | 87 | -------------------------------------------------------------------------------- /base/bind_this_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: bind_this_mgr.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 01/14/2015 09:50:55 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_BIND_THIS_MGR_H__ 20 | #define __CONET_BIND_THIS_MGR_H__ 21 | 22 | #include 23 | #include 24 | 25 | namespace conet 26 | { 27 | 28 | struct BindThisData 29 | { 30 | uint64_t jump_func; 31 | uint64_t self; 32 | uint64_t mem_func; 33 | uint64_t other; 34 | char code[32]; 35 | }; 36 | 37 | BindThisData * get_bind_this_data(); 38 | void free_bind_this_data(BindThisData *d); 39 | 40 | #define free_bind_this_func(f) \ 41 | ({ \ 42 | free_bind_this_data( \ 43 | (BindThisData *)((char*)f - ((size_t)&((BindThisData *)0)->code))); \ 44 | }) 45 | 46 | } 47 | 48 | #endif /* end of include guard */ 49 | 50 | -------------------------------------------------------------------------------- /base/bobhash.h: -------------------------------------------------------------------------------- 1 | #ifndef BOBHASH_H 2 | #define BOBHASH_H 3 | 4 | #include /* defines uint32_t etc */ 5 | uint32_t bob_hash( const void *key, size_t length, uint32_t initval); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /base/cpu_affinity.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: cpu_affinity.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月29日 05时33分48秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_CPU_AFFINITY_H__ 19 | #define __CONET_CPU_AFFINITY_H__ 20 | #include 21 | #include 22 | 23 | namespace conet 24 | { 25 | int parse_affinity(char const * txt, std::vector *cpu_sets); 26 | int parse_affinity(char const * txt, cpu_set_t *cpu_set); 27 | int set_cur_thread_cpu_affinity(int cpu_id); 28 | int set_proccess_cpu_affinity(int cpu_id); 29 | } 30 | 31 | #endif /* end of include guard */ 32 | -------------------------------------------------------------------------------- /base/defer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: defer.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年03月09日 15时54分04秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_DEFER_H__ 19 | #define __CONET_DEFER_H__ 20 | #include "macro_help.h" 21 | 22 | #define CONET_DEFER_DECL_TYPEOF(r, data, a) typedef typeof(a) BOOST_PP_CAT(typeof_, a) ; 23 | #define CONET_DEFER_IMPL_REF_TYPE(r, data, a) BOOST_PP_CAT(typeof_,a) &a; 24 | 25 | #define CONET_DEFER_PARAM_DEF(r1, data, i, a) BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(typeof_,a) & BOOST_PP_CAT(a,r) 26 | #define CONET_DEFER_PARAM_INIT(r1, data, i, a) BOOST_PP_COMMA_IF(i) a(BOOST_PP_CAT(a,r)) 27 | 28 | 29 | #define CONET_DEFER(...) \ 30 | BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1), \ 31 | CONET_DEFER_IMPL, CONET_DEFER_EMPTY_PARAM_IMPL) \ 32 | (__VA_ARGS__) 33 | 34 | #define CONET_DEFER_IMPL(param, op) CONET_DEFER_IMPL2(param, BOOST_PP_VARIADIC_TO_SEQ param, op) 35 | 36 | #define CONET_DEFER_IMPL2(param, param_seq , op) \ 37 | BOOST_PP_SEQ_FOR_EACH(CONET_DEFER_DECL_TYPEOF, data, param_seq) \ 38 | struct __conet_defer_t_##__LINE__ \ 39 | { \ 40 | BOOST_PP_SEQ_FOR_EACH(CONET_DEFER_IMPL_REF_TYPE, data, param_seq) \ 41 | explicit \ 42 | __conet_defer_t_##__LINE__ \ 43 | (\ 44 | BOOST_PP_SEQ_FOR_EACH_I(CONET_DEFER_PARAM_DEF, data, param_seq) \ 45 | ) :\ 46 | BOOST_PP_SEQ_FOR_EACH_I(CONET_DEFER_PARAM_INIT, data, param_seq) \ 47 | {}\ 48 | \ 49 | ~__conet_defer_t_##__LINE__()\ 50 | op \ 51 | } \ 52 | __conet_defer_var_##__LINE__ __attribute__((unused)) param\ 53 | 54 | 55 | #define CONET_DEFER_EMPTY_PARAM_IMPL(op) \ 56 | struct __conet_defer_t_##__LINE__ \ 57 | { \ 58 | ~__conet_defer_t_##__LINE__() \ 59 | op \ 60 | } __conet_defer_var_##__LINE__ __attribute__((unused)) \ 61 | 62 | #define CONET_SCOPE_EXIT CONET_DEFER 63 | 64 | 65 | #endif /* end of include guard */ 66 | 67 | -------------------------------------------------------------------------------- /base/fd_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: fd_queue.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月11日 05时21分17秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET__FD_QUEUE_H__ 19 | #define __CONET__FD_QUEUE_H__ 20 | 21 | #include 22 | 23 | namespace conet 24 | { 25 | 26 | //一写多读是安全的 27 | // 28 | struct FdQueue 29 | { 30 | 31 | // mmap 的 大小 32 | uint64_t alloc_size; 33 | 34 | // 最多 fd 数量 35 | uint64_t max_num; 36 | 37 | // 当前 fd 数量 38 | volatile uint64_t fd_num; 39 | 40 | // 读位置 41 | volatile uint64_t read_pos; 42 | 43 | // 写位置 44 | volatile uint64_t write_pos; 45 | 46 | volatile int64_t fds[0]; //8字节在64机器上保证了原子读写 47 | 48 | // 49 | static FdQueue * create(uint64_t max_num); 50 | 51 | static void free(FdQueue *q); 52 | 53 | 54 | // 没有句柄 55 | bool empty(); 56 | 57 | // 满了 58 | bool full(); 59 | 60 | // 61 | bool push_fd(int fd); 62 | 63 | // -1 表示没有 64 | int pop_fd(); 65 | 66 | }; 67 | 68 | 69 | } 70 | 71 | 72 | #endif /* end of include guard */ 73 | -------------------------------------------------------------------------------- /base/fifo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: fifo.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月27日 17时35分52秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_FIFO_H__ 19 | #define __CONET_FIFO_H__ 20 | 21 | #include "list.h" 22 | 23 | namespace conet 24 | { 25 | struct Fifo 26 | { 27 | 28 | struct Node 29 | { 30 | list_head link; 31 | void *value; 32 | Node() 33 | { 34 | INIT_LIST_HEAD(&link); 35 | } 36 | }; 37 | typedef Node node_type; 38 | 39 | list_head used_list; 40 | list_head free_list; 41 | 42 | int (*obj_fini_func)(void *, void *); 43 | void * obj_fini_arg; 44 | 45 | Fifo() 46 | { 47 | INIT_LIST_HEAD(&used_list); 48 | INIT_LIST_HEAD(&free_list); 49 | 50 | obj_fini_func = NULL; 51 | obj_fini_arg = NULL; 52 | } 53 | 54 | void push(void *v) 55 | { 56 | node_type *n = NULL; 57 | if (list_empty(&free_list)) { 58 | n = new node_type(); 59 | n->value = v; 60 | list_add_tail(&n->link, &used_list); 61 | } else { 62 | n = container_of(free_list.next, node_type, link); 63 | n->value = v; 64 | list_move_tail(&n->link, &used_list); 65 | } 66 | if (NULL == n) { 67 | n = new node_type(); 68 | } 69 | } 70 | 71 | 72 | bool empty() { 73 | return list_empty(&used_list); 74 | } 75 | 76 | void * pop() 77 | { 78 | if (list_empty(&used_list)) 79 | { 80 | return NULL; 81 | } 82 | node_type * n= container_of((used_list.next), node_type, link); 83 | list_move(&n->link, &free_list); 84 | return n->value; 85 | } 86 | 87 | void set_delete_obj_func(int (*fn)(void *arg, void * value), void *arg) 88 | { 89 | obj_fini_func = fn; 90 | obj_fini_arg = arg; 91 | } 92 | 93 | ~Fifo() 94 | { 95 | node_type *e = NULL; 96 | list_for_each_entry(e, &used_list, link) 97 | { 98 | if (obj_fini_func) 99 | { 100 | obj_fini_func(obj_fini_arg, e->value); 101 | } 102 | delete e; 103 | } 104 | list_for_each_entry(e, &free_list, link) 105 | { 106 | delete e; 107 | } 108 | } 109 | 110 | }; 111 | 112 | } 113 | 114 | 115 | #endif /* end of include guard */ 116 | -------------------------------------------------------------------------------- /base/fixed_mempool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: mem_pool.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月11日 04时39分46秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __MEM_POOL_H_INC__ 19 | #define __MEM_POOL_H_INC__ 20 | 21 | #include 22 | #include "list.h" 23 | 24 | namespace conet 25 | { 26 | 27 | struct fixed_mempool_t 28 | { 29 | uint64_t alloc_size; 30 | uint64_t total_num; 31 | uint64_t used_num; 32 | uint64_t free_num; 33 | uint64_t max_num; 34 | int32_t align_size; 35 | list_head free_list; 36 | 37 | struct { 38 | unsigned int is_page_alloc:1; 39 | }; 40 | 41 | fixed_mempool_t() 42 | { 43 | alloc_size = 0; 44 | total_num = 0; 45 | used_num = 0; 46 | free_num = 0; 47 | max_num = 0; 48 | align_size = 0; 49 | INIT_LIST_HEAD(&free_list); 50 | is_page_alloc = 0; 51 | } 52 | 53 | void * alloc(); 54 | void free(void *); 55 | int init(uint64_t alloc_size, uint64_t max_num, int align_size = 0); 56 | 57 | void fini(); 58 | 59 | // help function 60 | void * alloc_mem_help(); 61 | void free_mem_help(void *e); 62 | }; 63 | 64 | template 65 | class FixedMempool 66 | :public fixed_mempool_t 67 | { 68 | public: 69 | typedef T value_type; 70 | typedef fixed_mempool_t parent_type; 71 | 72 | explicit 73 | FixedMempool(int max_num = 10000) 74 | { 75 | init(sizeof(value_type), max_num, __alignof__(value_type)); 76 | 77 | } 78 | 79 | ~FixedMempool() 80 | { 81 | fini(); 82 | } 83 | 84 | value_type *alloc() 85 | { 86 | value_type *v = new ((parent_type::alloc())) value_type; 87 | return v; 88 | } 89 | 90 | void free(value_type *v) 91 | { 92 | //delete (v) value_type; 93 | parent_type::free(v); 94 | } 95 | }; 96 | 97 | } 98 | 99 | 100 | #endif /* end of include guard */ 101 | -------------------------------------------------------------------------------- /base/gcc_builtin_help.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: gcc_builtin_help.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月01日 01时46分27秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_GCC_BUILTIN_HELP_H__ 20 | #define __CONET_GCC_BUILTIN_HELP_H__ 21 | 22 | 23 | #define likely(x) __builtin_expect(!!(x), 1) 24 | #define unlikely(x) __builtin_expect(!!(x), 0) 25 | 26 | 27 | #endif /* end of include guard */ 28 | -------------------------------------------------------------------------------- /base/hashtable_lockfree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: hashtable_lockfree.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 04/06/2015 04:41:31 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_HASHTABLE_LOCK_FREE_H__ 20 | #define __CONET_HASHTABLE_LOCK_FREE_H__ 21 | 22 | 23 | namespace conet 24 | { 25 | 26 | //内容只允许添加, 不允许删除 27 | struct FixedHashTableLockFree 28 | { 29 | struct node_t 30 | { 31 | node_t * next; 32 | uint64_t key; 33 | void *value; 34 | } 35 | 36 | node_t * bucket; 37 | 38 | uint64_t bucket_num; 39 | 40 | int init(uint64_t num) 41 | { 42 | bucket = new node_t*[num]; 43 | bucket_num = (uint64_t)num; 44 | } 45 | 46 | FixedHashTableLockFree() 47 | { 48 | bucket = NULL; 49 | bucket_num = 0; 50 | } 51 | 52 | inline 53 | uint64_t hash_code(uint64_t key) 54 | { 55 | key = (~key) + (key << 21); // key = (key << 21) - key - 1; 56 | key = key ^ (key >> 24); 57 | key = (key + (key << 3)) + (key << 8); // key * 265 58 | key = key ^ (key >> 14); 59 | key = (key + (key << 2)) + (key << 4); // key * 21 60 | key = key ^ (key >> 28); 61 | key = key + (key << 31); 62 | return key; 63 | } 64 | 65 | 66 | int find(uint64_t key); 67 | 68 | 69 | int add(node_t * node) 70 | { 71 | uint64_t key = node->key; 72 | uint64_t hash = hash_code(key); 73 | uint64_t pos = hash % bucket_num; 74 | 75 | bucket + pos; 76 | 77 | } 78 | 79 | }; 80 | 81 | 82 | } 83 | 84 | #endif /* end of include guard */ 85 | 86 | -------------------------------------------------------------------------------- /base/http_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_PARSER_H 2 | #define HTTP_PARSER_H 3 | 4 | #include 5 | #include "ref_str.h" 6 | 7 | namespace conet 8 | { 9 | 10 | typedef struct http_header_t 11 | { 12 | ref_str_t name; 13 | ref_str_t value; 14 | } http_header_t; 15 | 16 | enum { 17 | CONNECTION_CLOSE=0, 18 | CONNECTION_KEEPALIVE=1, 19 | }; 20 | 21 | enum { 22 | METHOD_GET=0, 23 | METHOD_POST=1, 24 | }; 25 | 26 | enum { 27 | HTTP_REQUEST = 1, 28 | HTTP_RESPONSE = 1, 29 | }; 30 | 31 | enum { 32 | HTTP_1_0 =1, 33 | HTTP_1_1 =0, 34 | }; 35 | 36 | struct http_request_t 37 | { 38 | char * body; 39 | char * mark; 40 | char * query_start; 41 | char * header_start; 42 | char * header_val_start; 43 | 44 | int status; 45 | 46 | struct{ 47 | unsigned int err_too_many_header:1; 48 | unsigned int http_type:2; // 1 HTTP_REUQST, 2 HTTP_RESPONSE 49 | }; 50 | 51 | size_t content_length; 52 | size_t nread; 53 | 54 | int version; 55 | int method; 56 | int connection; 57 | int status_code; 58 | 59 | struct { 60 | unsigned int websocket:1; 61 | }; 62 | 63 | ref_str_t host; 64 | ref_str_t fragment; 65 | ref_str_t path; 66 | ref_str_t query_string; 67 | ref_str_t uri; 68 | ref_str_t upgrade; 69 | 70 | ref_str_t accept; 71 | ref_str_t content_type; 72 | ref_str_t reason_phrase; 73 | 74 | ref_str_t sec_websocket_key; 75 | ref_str_t sec_websocket_version; 76 | 77 | int headers_num; 78 | struct http_header_t headers[100]; 79 | 80 | char *rest_data; // 没有解析的数据 81 | size_t rest_len; 82 | 83 | } __attribute__((aligned(64))); 84 | 85 | void http_request_init(http_request_t *parser); 86 | 87 | int http_request_finish(http_request_t *parser); 88 | 89 | size_t http_request_parse(http_request_t *parser, char *data, size_t len, size_t off); 90 | 91 | int http_request_has_error(http_request_t *parser); 92 | 93 | int http_request_is_finished(http_request_t *parser); 94 | 95 | 96 | inline size_t http_request_nread(http_request_t *parser) 97 | { 98 | return parser->nread; 99 | } 100 | 101 | } 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /base/int_map.h: -------------------------------------------------------------------------------- 1 | /* * ===================================================================================== 2 | * 3 | * Filename: str_map.h 4 | * 5 | * Description: 6 | * 7 | * Version: 1.0 8 | * Created: 2014年10月08日 15时47分19秒 9 | * Revision: none 10 | * Compiler: gcc 11 | * 12 | * Author: piboyeliu 13 | * Organization: 14 | * 15 | * ===================================================================================== 16 | */ 17 | #ifndef INT_MAP_H_INCL 18 | #define INT_MAP_H_INCL 19 | 20 | #include "hash_table_base.h" 21 | 22 | namespace conet 23 | { 24 | 25 | class IntMap 26 | : public HashTableBase 27 | { 28 | public: 29 | 30 | static 31 | inline 32 | uint64_t hash_code(uint64_t key) 33 | { 34 | key = (~key) + (key << 21); // key = (key << 21) - key - 1; 35 | key = key ^ (key >> 24); 36 | key = (key + (key << 3)) + (key << 8); // key * 265 37 | key = key ^ (key >> 14); 38 | key = (key + (key << 2)) + (key << 4); // key * 21 39 | key = key ^ (key >> 28); 40 | key = key + (key << 31); 41 | return key; 42 | } 43 | 44 | }; 45 | 46 | } 47 | 48 | #endif /* end of include guard */ 49 | -------------------------------------------------------------------------------- /base/ip_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: ip_list.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月18日 11时17分18秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __IP_LIST_H_INC__ 19 | #define __IP_LIST_H_INC__ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "bobhash.h" 26 | 27 | struct ip_port_t 28 | { 29 | std::string ip; 30 | int port; 31 | }; 32 | 33 | inline 34 | bool operator<(ip_port_t const &lval, ip_port_t const &rval ) 35 | { 36 | int i = lval.ip.compare(rval.ip); 37 | if (i>0) return false; 38 | if (i<0) return true; 39 | return lval.port < rval.port; 40 | } 41 | 42 | inline 43 | bool operator==(ip_port_t const &lval, ip_port_t const &rval ) 44 | { 45 | int i = lval.ip.compare(rval.ip); 46 | if (i) return false; 47 | return lval.port == rval.port; 48 | } 49 | 50 | 51 | struct ip_port_hash_t 52 | { 53 | size_t operator()(ip_port_t const &val) const 54 | { 55 | size_t seed = 0; 56 | seed = bob_hash(val.ip.c_str(), val.ip.size(), 251); 57 | size_t seed2 = bob_hash(&val.port, sizeof(val.port), 251); 58 | seed = 3*seed + 23*seed2; 59 | return seed; 60 | } 61 | }; 62 | 63 | static 64 | inline 65 | void parse_ip_list(std::string txt, std::vector * list) 66 | { 67 | 68 | char * start = (char *) txt.c_str(); 69 | ip_port_t ip_port; 70 | char * p = NULL; 71 | p = strtok(start, ";"); 72 | while(p) 73 | { 74 | char * p2 = p; 75 | while ( *p2 != ':' && *p2 != 0) ++p2; 76 | if (*p2 == ':') { 77 | ip_port.ip.assign(p, p2); 78 | ip_port.port = atoi(p2+1); 79 | list->push_back(ip_port); 80 | } 81 | p = strtok(NULL, ";"); 82 | } 83 | return ; 84 | } 85 | 86 | #endif /* end of include guard */ 87 | -------------------------------------------------------------------------------- /base/macro_help.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: macro_help.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/19/2015 03:11:40 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_MACRO_HELP_H__ 19 | #define __CONET_MACRO_HELP_H__ 20 | 21 | #ifndef BOOST_PP_VARIADICS 22 | // gcc 必须定义这个, 不然会定义为 0, 导致 BOOST_PP_VARIADIC_TO_SEQ 用不了 23 | # define BOOST_PP_VARIADICS 2 24 | #endif 25 | 26 | #include "boost/preprocessor.hpp" 27 | 28 | #define CONET_ARG_DEF(z, n, t) \ 29 | BOOST_PP_COMMA_IF(n) \ 30 | BOOST_PP_CAT(arg_type_,n) BOOST_PP_CAT(arg, n) 31 | 32 | #endif /* end of include guard */ 33 | 34 | -------------------------------------------------------------------------------- /base/murmurhash3.h: -------------------------------------------------------------------------------- 1 | 2 | //----------------------------------------------------------------------------- 3 | // MurmurHash3 was written by Austin Appleby, and is placed in the public 4 | // domain. The author hereby disclaims copyright to this source code. 5 | 6 | #ifndef _MURMURHASH3_H_ 7 | #define _MURMURHASH3_H_ 8 | 9 | 10 | #include 11 | 12 | //----------------------------------------------------------------------------- 13 | 14 | void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ); 15 | 16 | void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out ); 17 | 18 | void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out ); 19 | 20 | uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed ); 21 | 22 | //----------------------------------------------------------------------------- 23 | 24 | #endif // _MURMURHASH3_H_ 25 | -------------------------------------------------------------------------------- /base/obj_pool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: obj_pool.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年09月17日 08时34分33秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef OBJ_POOL_H_INC 20 | #define OBJ_POOL_H_INC 21 | 22 | #include "lifo.h" 23 | 24 | namespace conet 25 | { 26 | 27 | struct obj_pool_t 28 | :public Lifo 29 | { 30 | typedef void * (*alloc_func_t)(void *); 31 | alloc_func_t m_alloc_func; 32 | void * m_alloc_arg; 33 | 34 | obj_pool_t() 35 | { 36 | m_alloc_func = NULL; 37 | m_alloc_arg = NULL; 38 | } 39 | 40 | void set_alloc_obj_func( void *(*fn)(void *arg), void *arg) 41 | { 42 | m_alloc_func = fn; 43 | m_alloc_arg = arg; 44 | } 45 | 46 | void * alloc() 47 | { 48 | void * obj = pop(); 49 | if (NULL == obj) { 50 | if (m_alloc_func) { 51 | return m_alloc_func(m_alloc_arg); 52 | } 53 | } 54 | return obj; 55 | } 56 | 57 | void release(void * obj) 58 | { 59 | push(obj); 60 | } 61 | }; 62 | 63 | template 64 | class ObjPool :public obj_pool_t 65 | { 66 | public: 67 | typedef obj_t obj_type; 68 | 69 | explicit 70 | ObjPool() 71 | { 72 | set_alloc_obj_func(new_obj_help, NULL); 73 | set_free_obj_func(delete_obj_help, NULL); 74 | } 75 | 76 | static 77 | void delete_obj_help(void *arg, void *obj) 78 | { 79 | obj_type *v = (obj_type *)(obj); 80 | delete v; 81 | } 82 | 83 | static void *new_obj_help(void *arg) 84 | { 85 | return new obj_type(); 86 | } 87 | 88 | ~ObjPool() 89 | { 90 | } 91 | 92 | obj_type * alloc() 93 | { 94 | return (obj_type *)obj_pool_t::alloc(); 95 | } 96 | 97 | void release(obj_type * obj) 98 | { 99 | obj_pool_t::release(obj); 100 | } 101 | 102 | }; 103 | 104 | } 105 | 106 | #endif /* end of include guard */ 107 | -------------------------------------------------------------------------------- /base/pb2json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: pb2json.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月27日 22时52分47秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef PB2JSON_H 20 | #define PB2JSON_H 21 | #include 22 | 23 | #include "google/protobuf/message.h" 24 | #include "jsoncpp/json.h" 25 | #include "jsoncpp/value.h" 26 | 27 | namespace conet 28 | { 29 | 30 | int pb2json(const google::protobuf::Message *msg, Json::Value * a_root); 31 | int pb2json(const google::protobuf::Message *msg, std::string *out); 32 | 33 | int pb2json(const google::protobuf::Descriptor *d, Json::Value * a_root); 34 | void pb2json(const google::protobuf::Descriptor *d, std::string *out); 35 | 36 | int json2pb( char const *txt, size_t len, 37 | google::protobuf::Message* message, 38 | std::string* error, bool urlencoded=false); 39 | 40 | int json2pb( 41 | Json::Value& json_value, 42 | google::protobuf::Message* message, 43 | std::string* error, 44 | bool urlencoded=false); 45 | 46 | 47 | int json2pb(std::string const & val, 48 | google::protobuf::Message* message, 49 | std::string* error, bool urlencoded=false); 50 | 51 | } 52 | 53 | #endif /* end of include guard */ 54 | -------------------------------------------------------------------------------- /base/pb2sqlite.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piboye/conet/fd61a3496bbf8c890de31c83d1b54a7189bf7f2e/base/pb2sqlite.h -------------------------------------------------------------------------------- /base/pb_obj_pool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: obj_pool.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月26日 22时40分33秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __PB_OBJ_POOL_H_INC__ 20 | #define __PB_OBJ_POOL_H_INC__ 21 | 22 | #include "google/protobuf/message.h" 23 | #include "obj_pool.h" 24 | 25 | namespace conet 26 | { 27 | 28 | class PbObjPool 29 | { 30 | public: 31 | google::protobuf::Message * m_obj_proto; 32 | google::protobuf::Arena arena; 33 | 34 | obj_pool_t m_queue; 35 | int m_hold_proto_flag; 36 | 37 | explicit 38 | PbObjPool() 39 | { 40 | m_hold_proto_flag = 0; 41 | m_obj_proto = NULL; 42 | } 43 | 44 | ~PbObjPool() 45 | { 46 | if (m_hold_proto_flag == 1) { 47 | delete m_obj_proto; 48 | } 49 | } 50 | 51 | static 52 | void * pb_obj_new(void *arg) 53 | { 54 | PbObjPool * self = (PbObjPool *)(arg); 55 | return self->m_obj_proto->New(&self->arena); 56 | } 57 | 58 | static 59 | void pb_obj_free(void *arg, void *obj) 60 | { 61 | //google::protobuf::Message * msg = (google::protobuf::Message *)(obj); 62 | //delete msg; 63 | } 64 | 65 | int init(google::protobuf::Message *pb, int hold=0) 66 | { 67 | if (m_hold_proto_flag && m_obj_proto) { 68 | delete m_obj_proto; 69 | } 70 | 71 | m_obj_proto = pb; 72 | 73 | m_hold_proto_flag = hold; 74 | 75 | m_queue.set_alloc_obj_func(&pb_obj_new, this); 76 | m_queue.set_free_obj_func(&pb_obj_free, this); 77 | 78 | return 0; 79 | } 80 | 81 | google::protobuf::Message * alloc() 82 | { 83 | return (google::protobuf::Message *) m_queue.alloc(); 84 | } 85 | 86 | void release(google::protobuf::Message *value) 87 | { 88 | return m_queue.release(value); 89 | } 90 | 91 | }; 92 | 93 | google::protobuf::Message * alloc_pb_obj_from_pool(google::protobuf::Message *proto); 94 | 95 | void free_pb_obj_to_pool(google::protobuf::Message *proto, google::protobuf::Message *obj); 96 | 97 | } 98 | 99 | #endif /* end of include guard */ 100 | -------------------------------------------------------------------------------- /base/ptr_cast.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: ptr_cast.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月02日 22时18分47秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __PTR_CAST_H__ 20 | #define __PTR_CAST_H__ 21 | 22 | #include 23 | 24 | namespace conet 25 | { 26 | template 27 | inline 28 | dst_fn_t ptr_cast(src_fn_t fn) 29 | { 30 | dst_fn_t ret_fn=NULL; 31 | memcpy(&(ret_fn), &(fn), sizeof(void *)); 32 | return ret_fn; 33 | } 34 | 35 | } // namespace conet 36 | 37 | #endif /* end of include guard */ 38 | -------------------------------------------------------------------------------- /base/query_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: query_string.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月28日 23时10分40秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef QUERY_STRING_H 20 | #define QUERY_STRING_H 21 | 22 | #include 23 | #include 24 | #include "jsoncpp/value.h" 25 | #include "jsoncpp/json.h" 26 | #include "thirdparty/protobuf/message.h" 27 | 28 | namespace conet 29 | { 30 | int parse_query_string(char const *buf, size_t len, std::map *param); 31 | 32 | int query_string_to_json(char const *buf, size_t len, Json::Value *root); 33 | 34 | int query_string_to_msg(char const *buf, size_t len, google::protobuf::Message *msg); 35 | } 36 | 37 | #endif /* end of include guard */ 38 | -------------------------------------------------------------------------------- /base/random.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: random.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月24日 08时33分40秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __RANDOM_H__ 20 | #define __RANDOM_H__ 21 | 22 | #include 23 | 24 | struct Rand 25 | { 26 | uint32_t x; 27 | uint32_t y; 28 | uint32_t z; 29 | uint32_t w; 30 | 31 | Rand() 32 | { 33 | reseed(uint32_t(0)); 34 | } 35 | 36 | Rand( uint32_t seed ) 37 | { 38 | reseed(seed); 39 | } 40 | 41 | void reseed ( uint32_t seed ) 42 | { 43 | x = 0x498b3bc5 ^ seed; 44 | y = 0; 45 | z = 0; 46 | w = 0; 47 | 48 | for(int i = 0; i < 10; i++) mix(); 49 | } 50 | 51 | void reseed ( uint64_t seed ) 52 | { 53 | x = 0x498b3bc5 ^ (uint32_t)(seed >> 0); 54 | y = 0x5a05089a ^ (uint32_t)(seed >> 32); 55 | z = 0; 56 | w = 0; 57 | 58 | for(int i = 0; i < 10; i++) mix(); 59 | } 60 | 61 | //----------------------------------------------------------------------------- 62 | 63 | void mix ( void ) 64 | { 65 | uint32_t t = x ^ (x << 11); 66 | x = y; y = z; z = w; 67 | w = w ^ (w >> 19) ^ t ^ (t >> 8); 68 | } 69 | 70 | uint32_t rand_u32 ( void ) 71 | { 72 | mix(); 73 | 74 | return x; 75 | } 76 | 77 | uint64_t rand_u64 ( void ) 78 | { 79 | mix(); 80 | 81 | uint64_t a = x; 82 | uint64_t b = y; 83 | 84 | return (a << 32) | b; 85 | } 86 | 87 | void rand_p ( void * blob, int bytes ) 88 | { 89 | uint32_t * blocks = reinterpret_cast(blob); 90 | 91 | while(bytes >= 4) 92 | { 93 | blocks[0] = rand_u32(); 94 | blocks++; 95 | bytes -= 4; 96 | } 97 | 98 | uint8_t * tail = reinterpret_cast(blocks); 99 | 100 | for(int i = 0; i < bytes; i++) 101 | { 102 | tail[i] = (uint8_t)rand_u32(); 103 | } 104 | } 105 | }; 106 | 107 | //----------------------------------------------------------------------------- 108 | 109 | extern Rand g_rand1; 110 | 111 | inline uint32_t rand_u32 ( void ) { return g_rand1.rand_u32(); } 112 | inline uint64_t rand_u64 ( void ) { return g_rand1.rand_u64(); } 113 | 114 | inline void rand_p ( void * blob, int bytes ) 115 | { 116 | uint32_t * blocks = (uint32_t*)blob; 117 | 118 | while(bytes >= 4) 119 | { 120 | *blocks++ = rand_u32(); 121 | bytes -= 4; 122 | } 123 | 124 | uint8_t * tail = (uint8_t*)blocks; 125 | 126 | for(int i = 0; i < bytes; i++) 127 | { 128 | tail[i] = (uint8_t)rand_u32(); 129 | } 130 | } 131 | 132 | #endif /* end of include guard */ 133 | -------------------------------------------------------------------------------- /base/redis_parse.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct redis_parser_t 8 | { 9 | void reinit(); 10 | 11 | // 参数个数 12 | int argnum=0; 13 | 14 | 15 | std::string_view *args=NULL; 16 | 17 | // 当前参数 18 | int cur_arg_pos=0; 19 | int cur_arg_size=0; 20 | char const * cur_arg_p=NULL; 21 | std::string_view *cur_arg=NULL; 22 | int cur_arg_char=0; 23 | 24 | enum { 25 | None=0, 26 | SET = 1, 27 | GET = 2, 28 | }; 29 | 30 | int cmd = 0; 31 | 32 | int status = 0; 33 | int nread = 0; 34 | 35 | uint64_t _reserve[100]; 36 | }; 37 | 38 | int redis_parser_exec(redis_parser_t *sc, const char *data, int len, int off); 39 | int redis_parser_finish(redis_parser_t *sc); -------------------------------------------------------------------------------- /base/ref_str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: ref_str.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月26日 18时27分12秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef REF_STR_H 20 | #define REF_STR_H 21 | #include 22 | #include 23 | #include 24 | 25 | namespace conet 26 | { 27 | 28 | typedef struct ref_str_t 29 | { 30 | uint32_t len; 31 | char * data; 32 | 33 | } ref_str_t; 34 | 35 | inline 36 | ref_str_t ref_str(char const * src, size_t len) 37 | { 38 | ref_str_t d; 39 | d.data = (char *)(src); 40 | d.len = (uint32_t) len; 41 | return d; 42 | } 43 | 44 | inline 45 | ref_str_t ref_str(std::string const &v) 46 | { 47 | ref_str_t d; 48 | d.data = (char *)v.data(); 49 | d.len = v.size(); 50 | return d; 51 | } 52 | 53 | inline 54 | void init_ref_str(ref_str_t *d, std::string const &v) 55 | { 56 | d->data = (char *)v.data(); 57 | d->len = v.size(); 58 | } 59 | 60 | inline 61 | void init_ref_str(struct ref_str_t * s, char const *start) 62 | { 63 | s->len = (uint32_t)strlen(start); 64 | s->data = (char *)start; 65 | } 66 | 67 | inline 68 | ref_str_t ref_str(char const * data) 69 | { 70 | ref_str_t d; 71 | init_ref_str(&d, data); 72 | return d; 73 | } 74 | 75 | inline 76 | void init_ref_str(struct ref_str_t * s, char const *start, size_t len) 77 | { 78 | s->len = (uint32_t)len; 79 | s->data = (char *)start; 80 | } 81 | 82 | inline 83 | void init_ref_str(struct ref_str_t * s, char const *start, char const * end) 84 | { 85 | s->len = (uint32_t)(end-start); 86 | s->data = (char *)start; 87 | } 88 | 89 | inline 90 | char * ref_str_to_cstr(struct ref_str_t *s, char *hold) 91 | { 92 | *hold = s->data[s->len]; 93 | s->data[s->len]=0; 94 | return s->data; 95 | } 96 | 97 | inline 98 | void ref_str_restore(struct ref_str_t *s, char hold) 99 | { 100 | s->data[s->len] = hold; 101 | } 102 | 103 | inline 104 | void ref_str_to(struct ref_str_t *src, std::string *out) 105 | { 106 | out->assign(src->data, src->len); 107 | } 108 | 109 | inline 110 | std::string ref_str_as_string(struct ref_str_t *src) 111 | { 112 | std::string out; 113 | out.assign(src->data, src->len); 114 | return out; 115 | } 116 | 117 | inline 118 | bool equal(ref_str_t const &l, ref_str_t const & r) 119 | { 120 | return (l.len == r.len) && (0 == (memcmp(l.data, r.data, l.len))); 121 | } 122 | 123 | 124 | } 125 | #endif /* end of include guard */ 126 | -------------------------------------------------------------------------------- /base/ref_str_tool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: ref_str_tool.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月29日 05时37分10秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include "ref_str.h" 19 | namespace conet 20 | { 21 | inline 22 | bool ref_str_empty(ref_str_t str) 23 | { 24 | return str.len == 0; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /base/scope_lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: scope_lock.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 04/06/2015 05:57:54 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_SCOPE_LOCK_H__ 19 | #define __CONET_SCOPE_LOCK_H__ 20 | 21 | #include 22 | 23 | namespace conet 24 | { 25 | class scope_lock 26 | { 27 | public: 28 | pthread_mutex_t *mutex; 29 | int cnt; 30 | explicit 31 | scope_lock(pthread_mutex_t *m) 32 | { 33 | mutex = m; 34 | cnt = 0; 35 | pthread_mutex_lock(m); 36 | 37 | } 38 | ~scope_lock() { 39 | pthread_mutex_unlock(mutex); 40 | } 41 | }; 42 | 43 | class scope_rdlock 44 | { 45 | public: 46 | pthread_rwlock_t *lock; 47 | int cnt; 48 | explicit 49 | scope_rdlock(pthread_rwlock_t *l) 50 | { 51 | lock = l; 52 | cnt = 0; 53 | pthread_rwlock_rdlock(l); 54 | 55 | } 56 | ~scope_rdlock() { 57 | pthread_rwlock_unlock(lock); 58 | } 59 | }; 60 | 61 | class scope_wrlock 62 | { 63 | public: 64 | pthread_rwlock_t *lock; 65 | int cnt; 66 | explicit 67 | scope_wrlock(pthread_rwlock_t *l) 68 | { 69 | lock = l; 70 | cnt = 0; 71 | pthread_rwlock_wrlock(l); 72 | } 73 | ~scope_wrlock() { 74 | pthread_rwlock_unlock(lock); 75 | } 76 | }; 77 | 78 | } 79 | 80 | #define SCOPE_RDLOCK(l) \ 81 | for (scope_rdlock scope_rdlock_##__LINE__ (l); scope_rdlock_##__LINE__.cnt <=0; scope_rdlock_##__LINE__.cnt=1) 82 | 83 | 84 | #define SCOPE_WRLOCK(l) \ 85 | for (scope_wrlock scope_wrlock_##__LINE__ (l); scope_wrlock_##__LINE__.cnt <=0; scope_wrlock_##__LINE__.cnt=1) 86 | 87 | 88 | #define SCOPE_LOCK(mutex) \ 89 | for (scope_lock scope_lock_##__LINE__ (mutex); scope_lock_##__LINE__.cnt <=0; scope_lock_##__LINE__.cnt=1) 90 | 91 | #endif /* end of include guard */ 92 | -------------------------------------------------------------------------------- /base/scoped_ptr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: scope_ptr.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月22日 17时12分40秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __SCOPED_PTR_H__ 19 | #define __SCOPED_PTR_H__ 20 | namespace conet 21 | { 22 | template 23 | class ScopedPtr 24 | { 25 | public: 26 | typedef T value_type; 27 | typedef T* ptr_type; 28 | typedef T* const_ptr_type; 29 | 30 | 31 | ptr_type m_ptr; 32 | 33 | explicit 34 | ScopedPtr(ptr_type p) 35 | { 36 | m_ptr = p; 37 | } 38 | 39 | value_type &operator *() const 40 | { 41 | return *m_ptr; 42 | } 43 | 44 | value_type *operator ->() const 45 | { 46 | return m_ptr; 47 | } 48 | 49 | value_type * get() const 50 | { 51 | return m_ptr; 52 | } 53 | 54 | value_type * release() 55 | { 56 | T * p = m_ptr; 57 | m_ptr = NULL; 58 | return p; 59 | } 60 | 61 | void reset(T *p= 0) 62 | { 63 | m_ptr = p; 64 | } 65 | 66 | ~ScopedPtr() 67 | { 68 | delete m_ptr; 69 | } 70 | 71 | private: 72 | //disable copy and assignment 73 | ScopedPtr(ScopedPtr const &right); 74 | ScopedPtr &operator=(ScopedPtr const &right); 75 | }; 76 | 77 | template 78 | void swap(ScopedPtr &a, ScopedPtr &b) 79 | { 80 | T * p1 = a.release(); 81 | T * p2 = b.release(); 82 | a.reset(p2); 83 | b.reset(p1); 84 | } 85 | } 86 | 87 | 88 | #endif /* end of include guard */ 89 | -------------------------------------------------------------------------------- /base/src/bind_this_jump.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl conet_bind_this_jump_help 3 | .type conet_bind_this_jump_help, @function 4 | .align 16 5 | conet_bind_this_jump_help: 6 | leaq -0x27(%rip), %rax# this instruction has 7 bytes 7 | movq 0x8(%rax), %r10 # this point 8 | movq 0x10(%rax), %r11 # method function address 9 | movq (%rax), %rax #function address 10 | jmp *%rax 11 | -------------------------------------------------------------------------------- /base/src/bind_this_mgr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: bind_this_mgr.cpp 5 | * 6 | * Description 7 | * 8 | * Version: 1.0 9 | * Created: 01/14/2015 11:37:06 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include "list.h" 19 | #include "bind_this_mgr.h" 20 | #include "tls.h" 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | extern "C" void conet_bind_this_jump_help(void); 27 | namespace conet 28 | { 29 | 30 | struct BindThisMgr 31 | { 32 | BindThisMgr() 33 | { 34 | INIT_LIST_HEAD(&m_free_list); 35 | } 36 | 37 | void expand() 38 | { 39 | size_t sz = 4096*4; 40 | void * p = mmap(0, sz, PROT_READ| PROT_WRITE | PROT_EXEC, 41 | MAP_PRIVATE | MAP_LOCKED | MAP_ANONYMOUS, -1, 0); 42 | 43 | list_head *n = NULL; 44 | for(size_t i= 0; i< sz; i+=64) 45 | { 46 | n = (list_head *)((char *)p+i); 47 | memcpy((void *)&(((BindThisData*)((char *)p+i))->code), 48 | (void *)(&conet_bind_this_jump_help), 32); 49 | INIT_LIST_HEAD(n); 50 | list_add_tail(n, &m_free_list); 51 | } 52 | } 53 | 54 | BindThisData *get_obj() 55 | { 56 | if (list_empty(&m_free_list)) 57 | { 58 | expand(); 59 | } 60 | list_head *n =list_pop_head(&m_free_list); 61 | return (BindThisData *)(n); 62 | } 63 | 64 | void free_obj(BindThisData *d) 65 | { 66 | list_head *n = (list_head *)(d); 67 | INIT_LIST_HEAD(n); 68 | list_add_tail(n, &m_free_list); 69 | } 70 | 71 | list_head m_free_list; 72 | }; 73 | 74 | 75 | static __thread BindThisMgr * g_bind_this_mgr=NULL; 76 | 77 | CONET_DEF_TLS_VAR_HELP_DEF(g_bind_this_mgr); 78 | 79 | BindThisData * get_bind_this_data() 80 | { 81 | return TLS_GET(g_bind_this_mgr)->get_obj(); 82 | } 83 | 84 | void free_bind_this_data(BindThisData *d) 85 | { 86 | return TLS_GET(g_bind_this_mgr)->free_obj(d); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /base/src/delay_init.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "delay_init.h" 3 | #include "macro_help.h" 4 | #include "plog.h" 5 | 6 | 7 | namespace delay_init { 8 | 9 | int failed_cnt = 0; 10 | int success_cnt = 0; 11 | int total_cnt = 0; 12 | int called_cnt = 0; 13 | 14 | #define INIT_LIST_HEAD_IMPL(s, index, name) BOOST_PP_COMMA_IF(index) LIST_HEAD_INIT(name[index]) 15 | 16 | list_head g_delay_init_list_head[INIT_LEVEL_NUM] = { 17 | BOOST_PP_REPEAT(INIT_LEVEL_NUM, INIT_LIST_HEAD_IMPL, g_delay_init_list_head) 18 | }; 19 | 20 | static int call_file_list(file_node *file_list) { 21 | if (file_list->called) { 22 | return 0; 23 | } 24 | PLOG_DEBUG("delay_init in file:", file_list->file_name); 25 | int ret = 0; 26 | list_head *q = NULL; 27 | list_for_each(q, &file_list->depend_list) { 28 | delay_init_depend_struct *depend = 29 | container_of(q, delay_init_depend_struct, link_to_depend); 30 | if (*(depend->point_file_node)) { 31 | ret += call_file_list(*(depend->point_file_node)); 32 | } 33 | } 34 | 35 | list_for_each(q, &file_list->init_list) { 36 | delay_init_struct *st = 37 | container_of(q, delay_init_struct, link_to_file); 38 | callback init = st->init; 39 | if (init) { 40 | if (0 == st->called) { 41 | PLOG_DEBUG("call delay init func:", st->info); 42 | ret += init(); 43 | ++st->called; 44 | ++called_cnt; 45 | } 46 | ++success_cnt; 47 | } else { 48 | ++failed_cnt; 49 | } 50 | ++total_cnt; 51 | } 52 | ++(file_list->called); 53 | return ret; 54 | } 55 | 56 | int call_in_level(int level) { 57 | if (level < 0 || INIT_LEVEL_NUM - 1 < level) { 58 | PLOG_ERROR("error init ", (level), " group"); 59 | return -1; 60 | } 61 | PLOG_DEBUG("delay_init in ", (level)); 62 | int ret = 0; 63 | list_head *q = NULL; 64 | list_for_each(q, &g_delay_init_list_head[level]) { 65 | file_node * file_list = container_of(q, file_node, link_to_root); 66 | ret += call_file_list(file_list); 67 | } 68 | return ret; 69 | } 70 | 71 | int call_all_level() { 72 | int ret = 0; 73 | for (int i = 0; i < INIT_LEVEL_NUM; ++i) { 74 | ret += call_in_level(i); 75 | } 76 | return ret; 77 | } 78 | 79 | } 80 | 81 | 82 | #ifdef ENABLE_DELAY_INIT_CPP_LOG 83 | #undef LOG 84 | #undef ENABLE_DELAY_INIT_CPP_LOG 85 | #endif //ENABLE_DELAY_INIT_CPP_LOG 86 | -------------------------------------------------------------------------------- /base/src/ebpf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int enable_reuseport_cbpf(int fd) 5 | { 6 | struct sock_filter code[] = { 7 | {BPF_LD | BPF_W | BPF_ABS, 0, 0, SKF_AD_OFF + SKF_AD_CPU}, 8 | {BPF_RET | BPF_A, 0, 0, 0}}; 9 | struct sock_fprog prog = { .len = 2, .filter = code }; 10 | return setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &prog, sizeof(prog)); 11 | } -------------------------------------------------------------------------------- /base/src/fixed_mempool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: mempool.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月29日 21时29分56秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "fixed_mempool.h" 23 | 24 | namespace conet 25 | { 26 | 27 | static int64_t g_page_size = sysconf(_SC_PAGESIZE); 28 | 29 | void * fixed_mempool_t::alloc_mem_help() 30 | { 31 | if (is_page_alloc) { 32 | return mmap(NULL, alloc_size, PROT_READ| PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 33 | } else { 34 | if (align_size > 1) { 35 | return malloc(alloc_size); 36 | } else { 37 | return memalign(align_size, alloc_size); 38 | } 39 | } 40 | } 41 | 42 | void fixed_mempool_t::free_mem_help(void *e) 43 | { 44 | if (is_page_alloc) { 45 | munmap(e, alloc_size); 46 | } else { 47 | ::free((void *)e); 48 | } 49 | } 50 | 51 | int fixed_mempool_t::init(uint64_t alloc_size, uint64_t max_num, int align_size) 52 | { 53 | this->max_num = max_num; 54 | if (g_page_size ==0) { 55 | g_page_size = sysconf(_SC_PAGESIZE); 56 | if (g_page_size <=0) { 57 | g_page_size = -1; 58 | } 59 | } 60 | 61 | if (g_page_size > 0 && alloc_size >= (uint64_t)g_page_size) { 62 | alloc_size = (alloc_size + g_page_size -1) / g_page_size * g_page_size; 63 | this->is_page_alloc = 1; 64 | } else { 65 | this->is_page_alloc = 0; 66 | if (align_size > 0) { 67 | alloc_size = (alloc_size + align_size -1) / align_size * align_size; 68 | } 69 | } 70 | this->alloc_size = alloc_size; 71 | this->align_size = align_size; 72 | return 0; 73 | } 74 | 75 | void *fixed_mempool_t::alloc() 76 | { 77 | list_head * n = list_pop_head(&free_list); 78 | if ( NULL == n) { 79 | n = (list_head *) alloc_mem_help(); 80 | ++this->total_num; 81 | } 82 | ++this->used_num; 83 | return n; 84 | } 85 | 86 | void fixed_mempool_t::free(void * obj) 87 | { 88 | list_head *n = (list_head *)(obj); 89 | INIT_LIST_HEAD(n); 90 | if (this->total_num >= this->max_num) 91 | { 92 | --this->total_num; 93 | free_mem_help(n); 94 | } else { 95 | list_add(n, &this->free_list); 96 | } 97 | --this->used_num; 98 | } 99 | 100 | void fixed_mempool_t::fini() 101 | { 102 | list_head *e = NULL, *n =NULL; 103 | list_for_each_safe(e, n, &this->free_list) 104 | { 105 | list_del(e); 106 | free_mem_help(e); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /base/src/random.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: random.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月24日 08时35分02秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include "random.h" 19 | 20 | Rand g_rand1(1); 21 | Rand g_rand2(2); 22 | Rand g_rand3(3); 23 | Rand g_rand4(4); 24 | -------------------------------------------------------------------------------- /base/src/redis_parse.rl: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "redis_parse.h" 6 | 7 | static int cs; 8 | 9 | %%{ 10 | machine RedisParser; 11 | 12 | action argnum_add_digit { sc->argnum = sc->argnum * 10 + (fc-'0'); } 13 | action argsize_reset { sc->cur_arg_size = 0; } 14 | action argsize_add_digit { sc->cur_arg_size = sc->cur_arg_size * 10 + (fc-'0'); } 15 | action args_init { 16 | sc->cur_arg_pos = -1; 17 | sc->args = (std::string_view *)sc->_reserve; 18 | } 19 | 20 | action arg_init { 21 | sc->cur_arg = &sc->args[++sc->cur_arg_pos]; 22 | sc->cur_arg_p = fpc+1; 23 | } 24 | 25 | action end_arg { 26 | *sc->cur_arg = std::string_view(sc->cur_arg_p, fpc-1-sc->cur_arg_p); 27 | if (sc->cur_arg_pos >= sc->argnum) { 28 | cs = RedisParser_first_final; 29 | } 30 | } 31 | 32 | action do_set_cmd{ 33 | sc->cmd = redis_parser_t::SET; 34 | sc->argnum = 2; 35 | } 36 | 37 | action do_get_cmd{ 38 | sc->cmd = redis_parser_t::GET; 39 | sc->argnum = 1; 40 | } 41 | 42 | redis_argnum = '*' ( digit @argnum_add_digit )+ '\r\n'; 43 | redis_argsize = '$' @argsize_reset ( digit @argsize_add_digit )+ '\r\n'; 44 | 45 | redis_arg_body = (any+)'\r\n' @end_arg; 46 | 47 | redis_args = (redis_argsize @arg_init redis_arg_body)+; 48 | get_cmd = '$3\r\nget\r\n' @do_get_cmd redis_args; 49 | set_cmd = '$3\r\nset\r\n' @do_set_cmd redis_args; 50 | redis_cmd = get_cmd | set_cmd; 51 | redis_expr = redis_argnum @args_init (redis_cmd); 52 | 53 | main := redis_expr; 54 | }%% 55 | 56 | %% write data; 57 | 58 | void redis_parser_t::reinit() { 59 | redis_parser_t * sc = this; 60 | sc->argnum = 0; 61 | sc->cmd = 0; 62 | sc->cur_arg_pos = 0; 63 | sc->status = 0; 64 | sc->nread = 0; 65 | %% write init; 66 | } 67 | 68 | int redis_parser_exec(redis_parser_t *sc, const char *data, int len, int off) { 69 | const char *p = data +off; 70 | const char *pe = data + len; 71 | int cs = sc->status; 72 | if (off > len) return -1; 73 | 74 | %% write exec; 75 | 76 | sc->status = cs; 77 | sc->nread += p - (data + off); 78 | return (sc->nread); 79 | } 80 | 81 | int redis_parser_finish(redis_parser_t *sc) { 82 | if (sc->status == RedisParser_error) return -1; 83 | else if (sc->status >= RedisParser_first_final) return 1; 84 | else return 0; 85 | } 86 | -------------------------------------------------------------------------------- /base/src/time_helper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: time_helper.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月18日 14时34分47秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include "time_helper.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace conet 26 | { 27 | 28 | uint64_t get_cpu_khz() 29 | { 30 | FILE *fp = fopen("/proc/cpuinfo","r"); 31 | if(!fp) return 1; 32 | char buf[4096] = {0}; 33 | size_t ret = 0; 34 | ret = fread(buf, 1, sizeof(buf), fp); 35 | fclose(fp); 36 | 37 | char *lp = strstr(buf,"cpu MHz"); 38 | if(!lp) return 1; 39 | lp += strlen("cpu MHz"); 40 | while(*lp == ' ' || *lp == '\t' || *lp == ':') 41 | { 42 | ++lp; 43 | } 44 | 45 | double mhz = atof(lp); 46 | uint64_t u = (uint64_t)(mhz * 1000); 47 | return u; 48 | } 49 | 50 | uint64_t __attribute__((weak)) get_tick_ms() 51 | { 52 | static uint64_t khz = get_cpu_khz(); 53 | return rdtscp() / khz; 54 | } 55 | 56 | 57 | uint64_t __attribute__((weak)) get_sys_ms() 58 | { 59 | struct timeval te; 60 | gettimeofday(&te, NULL); 61 | uint64_t ms = te.tv_sec*1000UL + te.tv_usec/1000; 62 | return ms; 63 | } 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /base/src/tls.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: tls.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 04/23/2014 05:33:42 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "tls.h" 23 | #include "list.h" 24 | #include "../plog.h" 25 | 26 | #define gettid() syscall(__NR_gettid) 27 | #define TLS_OUT_OF_INDEXES 0xffffffff 28 | 29 | namespace conet 30 | { 31 | struct pthread_atexit_t 32 | { 33 | void (*free_fn)(void *); 34 | void *arg; 35 | list_head link_to; 36 | }; 37 | 38 | 39 | static 40 | pthread_key_t g_pthread_atexit_key = TLS_OUT_OF_INDEXES; 41 | 42 | static 43 | pthread_once_t g_pthread_atexit_control_once = PTHREAD_ONCE_INIT; 44 | 45 | static 46 | void pthread_atexit_done(void *arg) 47 | { 48 | list_head *list = (list_head *) arg; 49 | if (NULL == list) return; 50 | pthread_atexit_t *id_ptr=NULL; 51 | 52 | list_head *it=NULL, *next=NULL; 53 | 54 | list_head l; 55 | INIT_LIST_HEAD(&l); 56 | list_add(&l, list); 57 | list_del_init(list); 58 | 59 | list_for_each_safe(it, next, &l) 60 | { 61 | list_del(it); 62 | id_ptr = container_of(it, pthread_atexit_t, link_to); 63 | if (id_ptr->free_fn) 64 | id_ptr->free_fn(id_ptr->arg); 65 | delete id_ptr; 66 | } 67 | delete list; 68 | } 69 | 70 | 71 | static void main_thread_atexit_done() 72 | { 73 | return pthread_atexit_done(pthread_getspecific(g_pthread_atexit_key)); 74 | } 75 | 76 | static 77 | void pthread_atexit_init(void) 78 | { 79 | pthread_key_create(&g_pthread_atexit_key, pthread_atexit_done); 80 | 81 | //主线程 退出释放资源 82 | atexit(&main_thread_atexit_done); 83 | } 84 | 85 | 86 | int tls_onexit_add(void *arg, void (*free_fn)(void *)) 87 | { 88 | pthread_once(&g_pthread_atexit_control_once, pthread_atexit_init); 89 | if (g_pthread_atexit_key == (pthread_key_t) TLS_OUT_OF_INDEXES) 90 | { 91 | PLOG_ERROR("pthread_atexit_key(", g_pthread_atexit_key, ") invalid"); 92 | return (-1); 93 | } 94 | 95 | list_head * list = (list_head *)pthread_getspecific(g_pthread_atexit_key); 96 | if (NULL == list) { 97 | list = (list_head *)new (list_head); 98 | INIT_LIST_HEAD(list); 99 | pthread_setspecific(g_pthread_atexit_key, list); 100 | } 101 | 102 | pthread_atexit_t *item = (pthread_atexit_t *)(new(pthread_atexit_t)); 103 | INIT_LIST_HEAD(&item->link_to); 104 | item->free_fn = free_fn; 105 | item->arg = arg; 106 | list_add(&item->link_to, list); 107 | return 0; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /base/src/to_lua_mgr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: to_lua_mgr.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月10日 11时26分48秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | 21 | #include "to_lua_mgr.h" 22 | 23 | namespace conet 24 | { 25 | 26 | static ToLuaMgr * get_global_to_lua_mgr() 27 | { 28 | 29 | static ToLuaMgr * g_to_lua_mgr = new ToLuaMgr(); 30 | return g_to_lua_mgr; 31 | } 32 | 33 | int ToLuaMgr::Add(int (*f)(lua_State *l), 34 | char const * name, char const * file, int line) 35 | { 36 | Item item; 37 | item.f = f; 38 | item.file = file; 39 | item.name = name; 40 | item.line = line; 41 | m_to_luas.push_back(item); 42 | return 0; 43 | } 44 | 45 | int ToLuaMgr::ToLua(lua_State *l) 46 | { 47 | for (size_t i=0; iAdd(f, name, file, line); 58 | } 59 | 60 | int ToLuaMgr::GlobalToLua(lua_State *l) 61 | { 62 | return get_global_to_lua_mgr()->ToLua(l); 63 | } 64 | 65 | 66 | } 67 | 68 | -------------------------------------------------------------------------------- /base/str_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: str_map.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月08日 15时47分19秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef STR_MAP_H_INCL 19 | #define STR_MAP_H_INCL 20 | 21 | #include "hash_table_base.h" 22 | #include "murmurhash3.h" 23 | #include "ref_str.h" 24 | 25 | namespace conet 26 | { 27 | 28 | class StrMap 29 | :public HashTableBase 30 | { 31 | public: 32 | static inline 33 | uint64_t hash_code(ref_str_t const &key) 34 | { 35 | return MurmurHash64A(key.data, key.len, 0); 36 | } 37 | 38 | static inline 39 | bool equal(ref_str_t const &l, ref_str_t const &r) 40 | { 41 | return conet::equal(l, r); 42 | } 43 | 44 | }; 45 | 46 | } 47 | 48 | #endif /* end of include guard */ 49 | -------------------------------------------------------------------------------- /base/string_builder.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_BUIDER_H_ 2 | #define _STRING_BUIDER_H_ 3 | #include 4 | #include 5 | 6 | namespace conet 7 | { 8 | template 9 | class StringBuilder 10 | { 11 | public: 12 | char m_buff[init_size]; 13 | std::string m_str; 14 | ssize_t m_len; 15 | StringBuilder() 16 | { 17 | m_len = 0; 18 | } 19 | 20 | void append(unsigned int n) { 21 | char s[20]={0}; 22 | char *p = s+sizeof(s)-1; 23 | int i =0 ; 24 | do { 25 | *p-- = "0123456789"[n%10]; 26 | n = n/10; 27 | i++; 28 | } while(n>0); 29 | ++p; 30 | append(p, i); 31 | } 32 | 33 | void append(std::string const &str) 34 | { 35 | size_t len = str.size(); 36 | char const *data = str.data(); 37 | append(data, len); 38 | } 39 | 40 | void append(std::string_view const &str) 41 | { 42 | size_t len = str.size(); 43 | char const *data = str.data(); 44 | append(data, len); 45 | } 46 | 47 | void append_ch(char ch) { 48 | if (m_len >=0) { 49 | if ((unsigned int)m_len < init_size) { 50 | m_buff[m_len++] = ch; 51 | return; 52 | } 53 | m_str.reserve(4 * init_size); 54 | m_len = -1; 55 | m_str.append(&m_buff[0], init_size); 56 | } 57 | 58 | m_str.push_back(ch); 59 | } 60 | 61 | void append(char const *data, size_t len) 62 | { 63 | size_t new_len = m_len + len; 64 | if (m_len >= 0) 65 | { 66 | if (new_len <= init_size) { 67 | memcpy(&m_buff[m_len], data, len); 68 | m_len = new_len; 69 | return; 70 | } 71 | m_str.reserve(4 * init_size); 72 | m_len = -1; 73 | m_str.append(&m_buff[0], init_size); 74 | } 75 | 76 | m_str.append(data, len); 77 | } 78 | 79 | char const *data() 80 | { 81 | if (m_len >= 0) 82 | { 83 | return &m_buff[0]; 84 | } 85 | return m_str.data(); 86 | } 87 | 88 | size_t size() 89 | { 90 | if (m_len >= 0) 91 | { 92 | return m_len; 93 | } 94 | 95 | return m_str.size(); 96 | } 97 | }; 98 | } 99 | 100 | #endif -------------------------------------------------------------------------------- /base/string_tpl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: string_tpl.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 07/06/2015 02:38:15 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_STRING_TPL_H__ 19 | #define __CONET_STRING_TPL_H__ 20 | 21 | #include 22 | #include 23 | 24 | namespace conet 25 | { 26 | 27 | static 28 | inline 29 | int string_tpl(std::string const &tpl, 30 | std::map const & datas, 31 | std::string *out, std::string *errmsg = NULL) 32 | { 33 | static char const * pre_tag="{{"; 34 | static char const * post_tag="}}"; 35 | size_t pre_tag_len = 2; 36 | size_t post_tag_len = 2; 37 | size_t cur_pos = 0; 38 | size_t pre_pos = 0; 39 | size_t end_pos = 0; 40 | 41 | for (;;) 42 | { 43 | cur_pos = tpl.find(pre_tag, pre_pos, pre_tag_len); 44 | if (cur_pos != std::string::npos) 45 | { 46 | out->append(tpl, pre_pos, cur_pos-pre_pos); 47 | end_pos = tpl.find(post_tag, cur_pos+pre_tag_len, post_tag_len); 48 | if (end_pos != std::string::npos) 49 | { 50 | std::string name(tpl, cur_pos+pre_tag_len, end_pos - cur_pos - (pre_tag_len)); 51 | typeof(datas.begin()) it = datas.find(name); 52 | if (it == datas.end()) { 53 | // no found name in data , error 54 | if (errmsg) { 55 | *errmsg = "no found key data, key:"; 56 | *errmsg += name; 57 | } 58 | return -1; 59 | } 60 | // replace data 61 | out->append(it->second); 62 | pre_pos = end_pos + post_tag_len; 63 | } else { 64 | // {{ not end with }} 65 | return -2; 66 | } 67 | } else { 68 | // complete all data 69 | out->append(tpl, pre_pos, cur_pos); 70 | break; 71 | } 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | } 78 | 79 | #endif /* end of include guard */ 80 | 81 | -------------------------------------------------------------------------------- /base/test/bind_this_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: bind_this_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年01月13日 19时59分07秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "bind_this.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "thirdparty/gtest/gtest.h" 31 | 32 | class A 33 | { 34 | public: 35 | int m_i; 36 | int f(int i, int j) 37 | { 38 | printf("m_i:%d hello, %d, %d\n", m_i, i, j); 39 | return i+j; 40 | } 41 | }; 42 | 43 | using namespace conet; 44 | 45 | TEST(bind_this, test) 46 | { 47 | A a; 48 | a.m_i = 100; 49 | int (*f)(int, int) = BindThis(a, A::f); 50 | int k = f(1, 2); 51 | printf("j:%d\n", k); 52 | ASSERT_EQ(3, k); 53 | free_bind_this_func(f); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /base/test/closure_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: functor_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月18日 05时43分03秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include "closure.h" 19 | #include 20 | #include 21 | #include "thirdparty/gtest/gtest.h" 22 | 23 | using namespace conet; 24 | TEST(closure, new_) 25 | { 26 | int c=1, b=2; 27 | closure_t *a = NewClosure(int, (int k), (c, b), 28 | { 29 | printf("hello k:%d, c:%d, d:%d\n", k, c, b); 30 | return k+c+b; 31 | }); 32 | ASSERT_EQ(6, a->Run(3)); 33 | delete a; 34 | 35 | closure_t *a2 = NewClosure(int,(), 36 | { 37 | printf("hello \n"); 38 | return 4; 39 | }); 40 | ASSERT_EQ(4, a2->Run()); 41 | delete a2; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /base/test/defer_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: defer_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年03月09日 16时56分29秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "defer.h" 20 | #include 21 | #include "thirdparty/gtest/gtest.h" 22 | 23 | void f(int *i) 24 | { 25 | CONET_DEFER((i), { 26 | *i = 4; 27 | }); 28 | *i=3; 29 | } 30 | 31 | TEST(defer, param1) 32 | { 33 | int a = 1; 34 | f(&a); 35 | ASSERT_EQ(4, a); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /base/test/http_parser_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: http_parser_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月26日 15时01分22秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "http_parser.h" 20 | #include "thirdparty/gtest/gtest.h" 21 | 22 | using namespace conet; 23 | 24 | TEST(http_request, parse) 25 | { 26 | http_request_t req; 27 | http_request_init(&req); 28 | char buff[]= 29 | "POST / HTTP/1.1\r\n" 30 | "A: a\r\n" 31 | "B: b\r\n" 32 | "Content-Length: 5\r\n" 33 | "Content-Type: text-plain\r\n" 34 | "\r\n" 35 | "fooba"; 36 | 37 | http_request_parse(&req, buff, sizeof(buff), 0); 38 | int status = http_request_finish(&req); 39 | printf("status:%d, %d\n", (int) req.status, (int)req.err_too_many_header); 40 | 41 | EXPECT_EQ(status, 1); 42 | EXPECT_EQ(5, (int)req.content_length); 43 | char hold = 0; 44 | EXPECT_STREQ("text-plain", ref_str_to_cstr(&req.content_type, &hold)); 45 | EXPECT_STREQ("a", ref_str_to_cstr(&req.headers[0].value, &hold)); 46 | EXPECT_STREQ("b", ref_str_to_cstr(&req.headers[1].value, &hold)); 47 | EXPECT_STREQ("fooba", req.body); 48 | } 49 | -------------------------------------------------------------------------------- /base/test/json_to_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: json_to_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 07/06/2015 01:32:32 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include "json_to.h" 21 | #include "gtest/gtest.h" 22 | #include 23 | 24 | namespace 25 | { 26 | 27 | struct A 28 | { 29 | int i; 30 | std::vector j; 31 | struct B 32 | { 33 | int k; 34 | int m; 35 | std::string name; 36 | DEF_JSON_TO_MEMBER(B, (k, m, name)) 37 | }; 38 | 39 | B b; 40 | }; 41 | 42 | DEF_JSON_TO(A, (i,j, b)) 43 | } 44 | 45 | 46 | 47 | 48 | TEST(json_to, test) 49 | { 50 | std::string json_txt="{\"i\":3, \"j\":[1,2,3,4], \"b\":{\"k\":5, \"m\":6, \"name\":\"abc\"}}"; 51 | A a; 52 | json_to(json_txt, &a); 53 | 54 | ASSERT_EQ(3, a.i); 55 | ASSERT_EQ(4, (int)a.j.size()); 56 | ASSERT_EQ(1, a.j[0]); 57 | 58 | ASSERT_EQ(5, a.b.k); 59 | ASSERT_EQ(6, a.b.m); 60 | 61 | ASSERT_STREQ("abc", a.b.name.c_str()); 62 | } 63 | -------------------------------------------------------------------------------- /base/test/module_a.cpp: -------------------------------------------------------------------------------- 1 | #include "../module.h" 2 | #include "../plog.h" 3 | 4 | DEFINE_MODULE(a) 5 | { 6 | PLOG_INFO("init module a"); 7 | return 0; 8 | } 9 | 10 | MODULE_FIN() 11 | { 12 | PLOG_INFO("fin module a"); 13 | return 0; 14 | } 15 | 16 | USING_MODULE(b); 17 | 18 | -------------------------------------------------------------------------------- /base/test/module_b.cpp: -------------------------------------------------------------------------------- 1 | #include "../module.h" 2 | #include "../plog.h" 3 | 4 | DEFINE_MODULE(b) 5 | { 6 | PLOG_INFO("init module b"); 7 | return 0; 8 | } 9 | 10 | MODULE_FIN() 11 | { 12 | PLOG_INFO("fin module b"); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /base/test/module_test.cpp: -------------------------------------------------------------------------------- 1 | #include "../module.h" 2 | #include "../plog.h" 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | InitAllModule(argc, argv); 7 | FinAllModule(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /base/test/pb2sqlite_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: tls_bench.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月31日 22时37分41秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "pb2sqlite.h" 20 | 21 | #include "base/test/test.pb.h" 22 | 23 | #include "../plog.h" 24 | #include "module.h" 25 | 26 | int main(int argc, char * argv[]) 27 | { 28 | InitAllModule(argc, argv); 29 | 30 | conet::Pb2Sqlite db; 31 | 32 | int ret = 0; 33 | 34 | Test d; 35 | 36 | ret = db.init("./test.db", "test"); 37 | if (ret) 38 | { 39 | PLOG_ERROR("init db failed!"); 40 | return 0; 41 | } 42 | 43 | db.create_table(d); 44 | 45 | d.set_id(2); 46 | d.set_name("abc"); 47 | db.insert(d); 48 | 49 | Test w; 50 | w.set_id(2); 51 | std::vector result; 52 | db.get_all(w, &result); 53 | for (size_t i=0; iDebugString()); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /base/test/plog_test.cpp: -------------------------------------------------------------------------------- 1 | #include "../plog.h" 2 | #include 3 | #include 4 | #include "module.h" 5 | 6 | std::string log_color(void *) 7 | { 8 | return " log color "; 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | InitAllModule(argc, argv); 14 | conet::PLog::Instance().SetColor(&log_color, NULL); 15 | 16 | PLOG_ERROR("wellcome"); 17 | PLOG(DEBUG, "ignore this msg"); 18 | PLOG(INFO, "hello ", "world"); 19 | PLOG(INFO, "my age: ", 18); 20 | PLOG_RAW(INFO, "my age: %d", 18); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /base/test/ptr_cast_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: fn_ptr_cast_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月02日 22时24分20秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "ptr_cast.h" 20 | #include 21 | #include "thirdparty/gtest/gtest.h" 22 | 23 | class A 24 | { 25 | public: 26 | int f(int b) 27 | { 28 | return b; 29 | } 30 | }; 31 | 32 | typedef int (*f_t)(void *arg, int); 33 | 34 | TEST(ptr_cast, test) 35 | { 36 | f_t f; 37 | 38 | f = conet::ptr_cast(&A::f); 39 | A a; 40 | 41 | int b = f(&a, 100); 42 | 43 | ASSERT_EQ(b, 100); 44 | } 45 | -------------------------------------------------------------------------------- /base/test/query_string_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: query_string_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月28日 23时20分18秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include "query_string.h" 21 | #include "thirdparty/gtest/gtest.h" 22 | 23 | 24 | using namespace conet; 25 | 26 | TEST(query_string, parse) 27 | { 28 | std::map params; 29 | std::string txt = "a=3&b=f4+"; 30 | int ret = 0; 31 | ret = parse_query_string(txt.c_str(), txt.size(), ¶ms); 32 | ASSERT_EQ(0, ret); 33 | ASSERT_STREQ("3", params["a"].c_str()); 34 | ASSERT_STREQ("f4+", params["b"].c_str()); 35 | } 36 | 37 | TEST(query_string, to_json) 38 | { 39 | std::string txt = "a=3&b=f4"; 40 | int ret = 0; 41 | Json::Value root; 42 | ret = query_string_to_json(txt.c_str(), txt.size(), &root); 43 | ASSERT_EQ(0, ret); 44 | printf("json:%s\n", root.toStyledString().c_str()); 45 | } 46 | -------------------------------------------------------------------------------- /base/test/string_tpl_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: string_tpl_test.cpp 5 | * 6 | * Description 7 | * 8 | * Version: 1.0 9 | * Created: 07/06/2015 02:53:46 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include "string_tpl.h" 21 | #include "gtest/gtest.h" 22 | #include 23 | #include 24 | #include "string2number.h" 25 | 26 | TEST(string_tpl, test) 27 | { 28 | std::string tpl="hello:{{name}}, age:{{age}}"; 29 | std::map datas; 30 | datas["name"]="piboye"; 31 | datas["age"] = conet::number2string(18); 32 | 33 | std::string out; 34 | std::string errmsg; 35 | 36 | int ret = 0; 37 | ret = conet::string_tpl(tpl, datas, &out, &errmsg); 38 | 39 | ASSERT_EQ(0, ret); 40 | 41 | ASSERT_STREQ("hello:piboye, age:18", out.c_str()); 42 | } 43 | -------------------------------------------------------------------------------- /base/test/test.proto: -------------------------------------------------------------------------------- 1 | message Test 2 | { 3 | optional int32 id=1; 4 | optional bytes name=2; 5 | }; 6 | -------------------------------------------------------------------------------- /base/test/time_helper_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: time_helper_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月01日 18时07分52秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include 21 | #include "tls.h" 22 | 23 | #include "gflags/gflags.h" 24 | #include "time_helper.h" 25 | #include "module.h" 26 | 27 | DEFINE_int32(num, 1000000, "num"); 28 | DEFINE_bool(sys_ms, false, "use gettimeofday to get ms"); 29 | 30 | 31 | int main(int argc, char * argv[]) 32 | { 33 | 34 | InitAllModule(argc, argv); 35 | if (FLAGS_sys_ms) 36 | { 37 | for(uint64_t i = (uint64_t)FLAGS_num; i > 0; --i) 38 | { 39 | conet::get_sys_ms(); 40 | } 41 | } else { 42 | for(uint64_t i = (uint64_t)FLAGS_num; i > 0; --i) 43 | { 44 | conet::get_tick_ms(); 45 | } 46 | 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /base/test/tls_bench.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: tls_bench.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月31日 22时37分41秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "tls.h" 20 | 21 | #include "gflags/gflags.h" 22 | #include "module.h" 23 | 24 | DEFINE_int32(num, 100000000, "swap num"); 25 | 26 | __thread int * g_i = NULL; 27 | 28 | CONET_DEF_TLS_VAR_HELP_DEF(g_i); 29 | 30 | int main(int argc, char * argv[]) 31 | { 32 | 33 | InitAllModule(argc, argv); 34 | for(uint64_t i = (uint64_t)FLAGS_num; i > 0; --i) 35 | { 36 | ++*TLS_GET(g_i); 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /base/test/to_json_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: to_json_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/19/2015 04:39:34 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "to_json.h" 20 | #include "gtest/gtest.h" 21 | 22 | namespace 23 | { 24 | struct A 25 | { 26 | int i; 27 | int j; 28 | struct B 29 | { 30 | int k; 31 | int m; 32 | DEF_TO_JSON_MEM(B, (k,m)) 33 | }; 34 | 35 | B b; 36 | }; 37 | 38 | DEF_TO_JSON(A, (i,j, b)) 39 | } 40 | 41 | TEST(to_json, test) 42 | { 43 | A a; 44 | a.i=3; 45 | a.j=4; 46 | a.b.k = 5; 47 | a.b.m = 6; 48 | std::string out; 49 | out = to_json(a); 50 | printf("%s", out.c_str()); 51 | } 52 | -------------------------------------------------------------------------------- /base/test/to_xml_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: to_xml_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/19/2015 07:17:07 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "to_xml.h" 20 | #include "gtest/gtest.h" 21 | 22 | struct A 23 | { 24 | int i; 25 | int j; 26 | struct B 27 | { 28 | int k; 29 | int m; 30 | DEF_TO_XML_MEM_WITH_ATTR("A", (k), (m)) 31 | }; 32 | 33 | B b; 34 | }; 35 | 36 | DEF_TO_XML(A, (i,j, b)) 37 | 38 | TEST(to_xml, serialize) 39 | { 40 | A a; 41 | a.i=3; 42 | a.j=4; 43 | a.b.k= 5; 44 | a.b.m= 6; 45 | std::string out; 46 | to_xml_value(out, a); 47 | printf("%s", out.c_str()); 48 | } 49 | -------------------------------------------------------------------------------- /base/test/url_encode_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: url_encode_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 05/28/2015 04:44:56 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include "thirdparty/gtest/gtest.h" 21 | #include "url_encode.h" 22 | 23 | using namespace conet; 24 | 25 | TEST(url_decode, decode) 26 | { 27 | std::string out; 28 | url_decode(std::string("%20abc"), &out); 29 | //ASSERT_EQ(3, (int)out.size()); 30 | ASSERT_STREQ(" abc", out.c_str()); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /base/time_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIME_HELPER_H_INC__ 2 | #define __TIME_HELPER_H_INC__ 3 | #include 4 | 5 | namespace conet 6 | { 7 | 8 | // rdtscp 比 rdtsc 更安全, 做了cpu同步 9 | inline 10 | uint64_t rdtscp(void) 11 | { 12 | volatile uint64_t tsc; 13 | __asm__ __volatile__("rdtscp; " // serializing read of tsc 14 | "shl $32,%%rdx; " // shift higher 32 bits stored in rdx up 15 | "or %%rdx,%%rax" // and or onto rax 16 | : "=a"(tsc) // output to tsc variable 17 | : 18 | : "%rcx", "%rdx"); // rcx and rdx are clobbered 19 | return tsc; 20 | } 21 | 22 | uint64_t get_cpu_khz(); 23 | 24 | uint64_t get_tick_ms(); 25 | 26 | uint64_t get_sys_ms(); 27 | 28 | } 29 | 30 | 31 | #define time_after(a,b) (((int64_t)(b) - (int64_t)(a))<0) 32 | #define time_before(a,b) time_after(b, a) 33 | 34 | #define time_after_eq(a,b) (((int64_t)(a) - (int64_t)(b))>=0) 35 | #define time_before_eq(a,b) time_after_eq(b, a) 36 | 37 | #define time_diff(a, b) ((int64_t)(a) - (int64_t)(b)) 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /base/to_lua_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: to_lua_mgr.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月10日 11时23分03秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_TO_LUA_MGR_H__ 20 | #define __CONET_TO_LUA_MGR_H__ 21 | 22 | #include 23 | #include 24 | 25 | struct lua_State; 26 | 27 | namespace conet 28 | { 29 | 30 | class ToLuaMgr 31 | { 32 | public: 33 | class Item 34 | { 35 | public: 36 | int (*f)(lua_State *l); 37 | int line; 38 | std::string file; 39 | std::string name; 40 | }; 41 | 42 | std::vector m_to_luas; 43 | 44 | int Add(int (*f)(lua_State *l), 45 | char const * name, char const * file, int line); 46 | 47 | int ToLua(lua_State *l); 48 | 49 | static 50 | int GlobalAdd(int (*f)(lua_State *l), 51 | char const * name, char const * file, int line); 52 | 53 | static 54 | int GlobalToLua(lua_State *l); 55 | }; 56 | 57 | 58 | #define REG_TO_LUA_HELP(name, lua_state) \ 59 | static int conet_reg_to_lua_help_func_##name##__LINE__(lua_State *lua_state); \ 60 | static int conet_reg_to_lua_help_var_##name##__LINE__ = ToLuaMgr::GlobalAdd(conet_reg_to_lua_help_func_##name##__LINE__,#name, __FILE__, __LINE__); \ 61 | static int conet_reg_to_lua_help_func_##name##__LINE__(lua_State *lua_state) \ 62 | 63 | 64 | 65 | } 66 | 67 | #endif /* end of include guard */ 68 | -------------------------------------------------------------------------------- /base/unix_socket_send_fd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: unix_socket_send_fd.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月11日 07时48分56秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_UNIX_SOCKET_SEND_FD_H__ 20 | #define __CONET_UNIX_SOCKET_SEND_FD_H__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "net_tool.h" 27 | 28 | 29 | namespace conet 30 | { 31 | 32 | struct UnixSocketSendFd 33 | { 34 | 35 | int unix_socks[2]; 36 | 37 | UnixSocketSendFd() 38 | { 39 | unix_socks[0]=-1; 40 | unix_socks[1]=-1; 41 | } 42 | 43 | ~UnixSocketSendFd() 44 | { 45 | close(unix_socks[0]); 46 | close(unix_socks[1]); 47 | } 48 | 49 | int init() 50 | { 51 | int ret = 0; 52 | ret = socketpair(AF_UNIX, SOCK_STREAM, 0, unix_socks); 53 | if (0 == ret) { 54 | set_none_block(unix_socks[0]); 55 | set_none_block(unix_socks[1]); 56 | } 57 | return ret; 58 | } 59 | 60 | 61 | inline 62 | int get_send_handle() 63 | { 64 | return unix_socks[0]; 65 | } 66 | 67 | inline 68 | int get_recv_handle() 69 | { 70 | return unix_socks[1]; 71 | } 72 | 73 | 74 | int send_fd(int fd); 75 | int recv_fd(std::vector *fds); 76 | 77 | }; 78 | 79 | } 80 | 81 | #endif /* end of include guard */ 82 | -------------------------------------------------------------------------------- /base/url_encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: url_encode.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月28日 23时54分26秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef URL_ENCODE_H 20 | #define URL_ENCODE_H 21 | 22 | 23 | #include 24 | namespace conet 25 | { 26 | 27 | void url_encode(char const * src , size_t len, std::string * out); 28 | void url_encode(std::string const & src, std::string * out); 29 | 30 | int url_decode(const std::string& src, std::string *out); 31 | 32 | int url_decode(char const * src, size_t len, std::string *out); 33 | 34 | } 35 | #endif /* end of include guard */ 36 | 37 | -------------------------------------------------------------------------------- /build_all.sh: -------------------------------------------------------------------------------- 1 | #/usr/bin/env bash 2 | (cd base; blade build $*) 3 | (cd core; blade build $*) 4 | (cd svrkit; blade build $*) 5 | (cd example; blade build $*) 6 | 7 | -------------------------------------------------------------------------------- /clang_env.sh: -------------------------------------------------------------------------------- 1 | export CPP="clang -E" 2 | export CC=clang 3 | export CXX="clang++ -Wno-error=format-nonliteral -Wno-error=invalid-source-encoding" 4 | export LD=clang++ 5 | -------------------------------------------------------------------------------- /code_summary.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ./tools/code_stats.sh --c++ --js --html core base example svrkit 3 | -------------------------------------------------------------------------------- /core/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = 'conet', 3 | srcs = [ 4 | 'src/swap_context.s', 5 | "src/version.cpp", 6 | "src/wait_queue.cpp", 7 | "src/coroutine.cpp", 8 | "src/coroutine_env.cpp", 9 | "src/gc.cpp", 10 | "src/network.cpp", 11 | #"src/network_safe.cpp", 12 | "src/fd_ctx.cpp", 13 | "src/network_hook.cpp", 14 | "src/pthread_hook.cpp", 15 | "src/disk_io_hook.cpp", 16 | "src/timewheel.cpp", 17 | "src/dispatch.cpp", 18 | "src/co_pool.cpp", 19 | "src/stacktrace.cpp", 20 | "src/jump_x86_64_sysv_elf_gas.s", 21 | "src/make_x86_64_sysv_elf_gas.s", 22 | "src/time_hook.cpp", 23 | "src/ares_wrap.cpp", 24 | "src/time_mgr.cpp", 25 | "src/common.cpp", 26 | #"src/malloc_hook.cpp", 27 | ], 28 | 29 | incs= [ 30 | "./", 31 | ], 32 | 33 | deps=[ 34 | '//base:base', 35 | '//thirdparty/gflags:gflags', 36 | '//thirdparty/glog:glog', 37 | '//thirdparty/c-ares:c-ares', 38 | '#aio', 39 | '#dl', 40 | '#pthread', 41 | '#rt', 42 | ], 43 | 44 | extra_cppflags=["-Wno-error=empty-body"], 45 | export_incs=["./"], 46 | link_all_symbols = True, 47 | #export_dynamic = True, 48 | ); 49 | 50 | 51 | 52 | cc_binary( 53 | name = 'co_swap_test', 54 | incs= [ 55 | "./", 56 | ], 57 | srcs = ['src/co_swap_test.cpp'], 58 | deps = [ 59 | ':conet', 60 | ], 61 | ); 62 | 63 | cc_binary( 64 | name = 'gethostbyname_test', 65 | incs= [ 66 | "./", 67 | ], 68 | srcs = ['src/gethostbyname_test.cpp'], 69 | deps = [ 70 | ':conet', 71 | ], 72 | ); 73 | 74 | -------------------------------------------------------------------------------- /core/co_pool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: co_pool.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年06月25日 10时39分09秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef CO_POLL_H_INC 19 | #define CO_POLL_H_INC 20 | 21 | #include "conet_all.h" 22 | namespace conet 23 | { 24 | 25 | struct co_pool_item_t 26 | { 27 | conet::coroutine_t *co; 28 | list_head link; 29 | }; 30 | 31 | struct co_pool_t 32 | { 33 | list_head free_list; 34 | list_head used_list; 35 | int total_num; 36 | int max_num; 37 | }; 38 | 39 | void init_co_pool(co_pool_t *pool, int max_num); 40 | 41 | } 42 | 43 | #endif /* end of include guard */ 44 | -------------------------------------------------------------------------------- /core/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: common.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/24/2015 02:39:58 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_COMMON_H__ 19 | #define __CONET_COMMON_H__ 20 | #include "base/list.h" 21 | 22 | namespace conet 23 | { 24 | int init_conet_global_env(); 25 | int free_conet_global_env(); 26 | 27 | int init_conet_env(); 28 | int free_conet_env(); 29 | } 30 | #endif /* end of include guard */ 31 | -------------------------------------------------------------------------------- /core/conet_all.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: all.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 16时35分20秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_ALL_H__ 19 | #define __CONET_ALL_H__ 20 | 21 | #include "coroutine.h" 22 | #include "network_hook.h" 23 | #include "pthread_hook.h" 24 | #include "dispatch.h" 25 | #include "common.h" 26 | 27 | #endif /* end of include guard */ 28 | 29 | -------------------------------------------------------------------------------- /core/dispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: dispatch.h 5 | * 6 | * Description: 任务分发器 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 17时23分51秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __DISPATCH_H_INC__ 19 | #define __DISPATCH_H_INC__ 20 | 21 | #include 22 | #include "base/list.h" 23 | 24 | namespace conet 25 | { 26 | 27 | typedef int (*task_proc_func_t)(void *); 28 | struct task_t 29 | { 30 | int (*proc)(void *); 31 | void *arg; 32 | list_head link_to; 33 | int auto_del; 34 | }; 35 | 36 | struct coroutine_env_t; 37 | struct dispatch_mgr_t 38 | { 39 | //任务 40 | list_head tasks; 41 | //延迟任务 42 | list_head delay_tasks; 43 | 44 | uint32_t task_num; 45 | uint32_t delay_task_num; 46 | coroutine_env_t *co_env; 47 | 48 | explicit 49 | dispatch_mgr_t(coroutine_env_t *env); 50 | 51 | ~dispatch_mgr_t(); 52 | 53 | // 注册任务 54 | void registry(task_t *task); 55 | 56 | //注销任务 57 | void unregistry(task_t *task); 58 | 59 | // 延迟执行一次任务 60 | void delay(task_t*); 61 | 62 | void unregistry_delay(task_t *task); 63 | }; 64 | 65 | 66 | void init_task(task_t *task, task_proc_func_t proc, void *arg); 67 | void registry_task(list_head *list, task_proc_func_t proc, void *arg); 68 | void registry_task(list_head *list, task_t *task); 69 | 70 | void registry_task(task_proc_func_t proc, void *arg); 71 | void registry_task(task_t *task); 72 | 73 | void unregistry_task(task_t *task); 74 | 75 | void registry_delay_task(task_t *task); 76 | void registry_delay_task(task_proc_func_t proc, void *arg); 77 | 78 | int proc_tasks(list_head *list); 79 | int dispatch(); 80 | 81 | int proc_delay_back(void *arg); 82 | void delay_back(); 83 | 84 | } 85 | 86 | #endif /* end of include guard */ 87 | -------------------------------------------------------------------------------- /core/event_notify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: event_notify.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月02日 02时23分18秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_EVENT_NOTIFY_H__ 20 | #define __CONET_EVENT_NOTIFY_H__ 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "coroutine.h" 28 | #include "network_hook.h" 29 | #include "fd_ctx.h" 30 | 31 | namespace conet 32 | { 33 | 34 | struct event_notify_t 35 | { 36 | int fd; 37 | uint64_t event_num; 38 | 39 | typedef int (*cb_type)(void *arg, uint64_t event) ; 40 | cb_type cb; 41 | void *cb_arg; 42 | int stop_flag; 43 | 44 | coroutine_t * work_co; 45 | 46 | int init(cb_type cb, void *cb_arg) 47 | { 48 | int evfd = 0; 49 | evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 50 | if (evfd <0) return -1; 51 | fd_ctx_t *ev_ctx = alloc_fd_ctx(evfd, 1); 52 | ev_ctx->user_flag &= ~O_NONBLOCK; 53 | 54 | this->fd = evfd; 55 | this->event_num = 0; 56 | this->work_co = alloc_coroutine(proc, this, 128*1024); 57 | if (NULL == this->work_co) { 58 | close(this->fd); 59 | this->fd = -1; 60 | return -2; 61 | } 62 | 63 | this->cb = cb; 64 | this->cb_arg = cb_arg; 65 | this->stop_flag = 0; 66 | //set_auto_delete(this->work_co); 67 | conet::resume(this->work_co); 68 | return 0; 69 | } 70 | 71 | static int proc(void *arg) 72 | { 73 | event_notify_t *self = (event_notify_t *)(arg); 74 | 75 | conet::enable_sys_hook(); 76 | 77 | do 78 | { 79 | uint64_t ready = 0; 80 | int n = 0; 81 | n = read(self->fd, &ready, 8); 82 | if((n == 8) && ready > 0) { 83 | self->event_num = ready; 84 | if (self->cb) { 85 | self->cb(self->cb_arg, ready); 86 | } 87 | } 88 | } while(!self->stop_flag); 89 | 90 | close(self->fd); 91 | self->fd = -1; 92 | return 0; 93 | } 94 | 95 | int notify(uint64_t num=1) 96 | { 97 | return syscall(SYS_write, this->fd, &num, sizeof(num)); 98 | } 99 | 100 | int stop() 101 | { 102 | this->stop_flag = 1; 103 | conet::resume(this->work_co); 104 | int ret = wait(this->work_co); 105 | conet::free_coroutine(this->work_co); 106 | this->work_co = NULL; 107 | return ret; 108 | } 109 | }; 110 | 111 | } 112 | #endif /* end of include guard */ 113 | -------------------------------------------------------------------------------- /core/fcontext.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONET_FCONTEXT_H__ 2 | #define __CONET_FCONTEXT_H__ 3 | 4 | #include 5 | 6 | namespace conet 7 | { 8 | 9 | struct stack_t 10 | { 11 | void *sp; 12 | uint64_t size; 13 | 14 | stack_t() : 15 | sp(NULL), size(0) 16 | { 17 | 18 | } 19 | }; 20 | 21 | struct fp_t 22 | { 23 | uint32_t fc_freg[2]; 24 | 25 | fp_t() : 26 | fc_freg() 27 | {} 28 | }; 29 | 30 | struct fcontext_t 31 | { 32 | uint64_t fc_greg[8]; 33 | stack_t fc_stack; 34 | fp_t fc_fp; 35 | 36 | fcontext_t() : 37 | fc_greg(), 38 | fc_stack(), 39 | fc_fp() 40 | {} 41 | }; 42 | 43 | extern "C" 44 | void *jump_fcontext(fcontext_t **cur_ctx, fcontext_t *dest_ctx, 45 | void *vp, bool preserve_fpu = true); 46 | 47 | extern "C" 48 | fcontext_t *make_fcontext(void * sp, uint64_t size, void (* fn)(void *) ); 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /core/fd_ctx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: fd_ctx.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月06日 15时53分39秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __FD_CTX_H_INC__ 20 | #define __FD_CTX_H_INC__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "base/list.h" 28 | 29 | namespace conet 30 | { 31 | 32 | struct fd_ctx_t 33 | { 34 | enum { 35 | SOCKET_FD_TYPE=1, 36 | DISK_FD_TYPE=2, 37 | TIMER_FD_TYPE=3, 38 | }; 39 | struct sockaddr_in dest; //maybe sockaddr_un; 40 | int type; 41 | int fd; 42 | int user_flag; 43 | int closed; 44 | 45 | int rcv_timeout; 46 | int snd_timeout; 47 | int domain; 48 | }; 49 | 50 | struct fd_ctx_mgr_t 51 | { 52 | fd_ctx_t **fds; 53 | int size; 54 | }; 55 | 56 | 57 | int init_fd_ctx_env(); 58 | 59 | 60 | fd_ctx_t * alloc_fd_ctx(int fd, int type=1); 61 | 62 | fd_ctx_t * alloc_fd_ctx2(int fd, int type, int has_nonblocked); 63 | 64 | extern fd_ctx_mgr_t *g_fd_ctx_mgr; 65 | 66 | int get_default_fd_ctx_size(); 67 | fd_ctx_mgr_t *create_fd_ctx_mgr(int size); 68 | inline fd_ctx_mgr_t * get_fd_ctx_mgr() 69 | { 70 | if (!g_fd_ctx_mgr) { 71 | g_fd_ctx_mgr = create_fd_ctx_mgr(get_default_fd_ctx_size()); 72 | } 73 | return g_fd_ctx_mgr; 74 | } 75 | fd_ctx_t *get_fd_ctx(int fd, int type=1); 76 | 77 | int free_fd_ctx(int fd); 78 | 79 | 80 | void fd_ctx_expand(fd_ctx_mgr_t *mgr, int need_size); 81 | 82 | inline 83 | fd_ctx_t *get_fd_ctx(int fd, int type) 84 | { 85 | if (fd <0) return NULL; 86 | 87 | fd_ctx_mgr_t *mgr = g_fd_ctx_mgr; 88 | 89 | if (fd >= mgr->size ) { 90 | fd_ctx_expand(mgr, fd+1); 91 | } 92 | 93 | fd_ctx_t *ctx = mgr->fds[fd]; 94 | if (NULL == ctx) { 95 | /* 96 | struct stat sb; 97 | int ret = fstat(fd, &sb); 98 | if (ret) return NULL; 99 | if (S_ISSOCK(sb.st_mode)) { 100 | return alloc_fd_ctx(fd, fd_ctx_t::SOCKET_FD_TYPE); 101 | } 102 | if (S_ISFIFO(sb.st_mode)) { 103 | return alloc_fd_ctx(fd, fd_ctx_t::SOCKET_FD_TYPE); 104 | } 105 | if (S_ISCHR(sb.st_mode)) { 106 | return alloc_fd_ctx(fd, fd_ctx_t::SOCKET_FD_TYPE); 107 | } 108 | // because FILE read buffer, can't hook 109 | if (S_ISREG(sb.st_mode)) { 110 | return alloc_fd_ctx(fd, fd_ctx_t::DISK_FD_TYPE); 111 | } 112 | */ 113 | return NULL; 114 | } 115 | 116 | if (type == 0) return ctx; 117 | 118 | if (ctx->type == type) { 119 | return ctx; 120 | } 121 | return NULL; 122 | } 123 | 124 | 125 | } 126 | 127 | #endif /* end of include guard */ 128 | -------------------------------------------------------------------------------- /core/hook_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: hook_helper.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 03时44分00秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __HOOK_HELLPER_H__ 19 | #define __HOOK_HELLPER_H__ 20 | 21 | #include 22 | 23 | #define SYS_FUNC(name) g_sys_##name##_func 24 | #define _(name) SYS_FUNC(name) 25 | 26 | #define HOOK_SYS_FUNC_DEF(ret_type, name, proto) \ 27 | typedef ret_type (* name##_pfn_t) proto; \ 28 | name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name); \ 29 | extern "C" ret_type name proto __attribute__ ((visibility ("default"))); \ 30 | extern "C" ret_type name proto \ 31 | 32 | #define HOOK_FUNC_DEF_THROW(ret_type, name, proto) \ 33 | typedef ret_type (* name##_pfn_t) proto; \ 34 | extern "C" name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name); \ 35 | extern "C" ret_type name proto __THROW \ 36 | 37 | #define HOOK_CPP_FUNC_DEF_NOTHROW(ret_type, name, proto) \ 38 | typedef ret_type (* name##_pfn_t) proto; \ 39 | name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name); \ 40 | ret_type name proto throw() \ 41 | 42 | #define HOOK_CPP_FUNC_DEF(ret_type, name, proto) \ 43 | typedef ret_type (* name##_pfn_t) proto; \ 44 | name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name); \ 45 | ret_type name proto \ 46 | 47 | #define HOOK_SYS_FUNC(name) if( !_(name)) { _(name) = (name##_pfn_t)dlsym(RTLD_NEXT,#name); } 48 | 49 | #define HOOK_DECLARE(ret_type, name, proto) \ 50 | typedef ret_type (* name##_pfn_t) proto; \ 51 | extern "C" name##_pfn_t _(name) 52 | 53 | #define HOOK_FUNC_DEF(ret_type, name, proto) \ 54 | typedef ret_type (* name##_pfn_t) proto; \ 55 | name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name) ; \ 56 | ret_type name proto \ 57 | 58 | 59 | #define HOOK_FUNC(name) \ 60 | do { \ 61 | if( !_(name)) { \ 62 | _(name) = (name##_pfn_t) dlsym(RTLD_NEXT,#name); \ 63 | } \ 64 | } while(0) \ 65 | 66 | #endif /* end of include guard */ 67 | -------------------------------------------------------------------------------- /core/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: log.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月07日 17时02分45秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CO_LOG_H_INC__ 19 | #define __CO_LOG_H_INC__ 20 | #include 21 | #include "../base/plog.h" 22 | 23 | #define LOG_SYS_CALL(func, ret) \ 24 | PLOG_ERROR("syscall ", #func , " failed, [ret:", ret, "]" \ 25 | "[errno:", errno, "]" \ 26 | "[errmsg:", strerror(errno), "]")\ 27 | 28 | #endif //__CO_LOG_H_INC__ 29 | -------------------------------------------------------------------------------- /core/network_hook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: network_hook.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 17时09分00秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __NETWORK_HOOK_H__ 19 | #define __NETWORK_HOOK_H__ 20 | 21 | #include 22 | 23 | #include "coroutine_env.h" 24 | 25 | namespace conet 26 | { 27 | 28 | void disable_sys_hook(); 29 | void enable_sys_hook(); 30 | int is_enable_sys_hook(); 31 | 32 | inline 33 | int is_enable_sys_hook() 34 | { 35 | coroutine_t *co = get_curr_co_can_null(); 36 | return co && !co->is_main && (co->is_enable_sys_hook); 37 | } 38 | 39 | inline 40 | void enable_sys_hook() 41 | { 42 | 43 | coroutine_t *co = get_curr_co_can_null(); 44 | if (co) 45 | co->is_enable_sys_hook = 1; 46 | } 47 | 48 | inline 49 | void disable_sys_hook() 50 | { 51 | coroutine_t *co = get_curr_co_can_null(); 52 | if (co) 53 | co->is_enable_sys_hook = 0; 54 | } 55 | 56 | 57 | int my_accept4( int fd, struct sockaddr *addr, socklen_t *len, int flags); 58 | ssize_t poll_recv( int fd, void *buffer, size_t length, int timeout); 59 | 60 | } 61 | 62 | #endif /* end of include guard */ 63 | -------------------------------------------------------------------------------- /core/pthread_hook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: pthread_hook.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 17时07分33秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __PTHREAD_HOOK_H__ 19 | #define __PTHREAD_HOOK_H__ 20 | 21 | #include "coroutine_env.h" 22 | 23 | namespace conet 24 | { 25 | 26 | int is_enable_pthread_hook(); 27 | void enable_pthread_hook(); 28 | void disable_pthread_hook(); 29 | 30 | inline 31 | int is_enable_pthread_hook() 32 | { 33 | coroutine_t *co = get_curr_co_can_null(); 34 | return co && !co->is_main && (co->is_enable_pthread_hook); 35 | } 36 | 37 | inline 38 | void enable_pthread_hook() 39 | { 40 | coroutine_t *co = get_curr_co_can_null(); 41 | if (co) 42 | co->is_enable_pthread_hook = 1; 43 | } 44 | 45 | inline 46 | void disable_pthread_hook() 47 | { 48 | coroutine_t *co = get_curr_co_can_null(); 49 | if (co) 50 | co->is_enable_pthread_hook = 0; 51 | } 52 | 53 | inline void disable_pthread_hook_save(int *stat) 54 | { 55 | coroutine_t *co = get_curr_co_can_null(); 56 | if (co) { 57 | *stat = co->is_enable_pthread_hook; 58 | co->is_enable_pthread_hook = 0; 59 | } else { 60 | *stat = 0; 61 | } 62 | } 63 | 64 | inline void restore_pthread_hook_stat(int stat) 65 | { 66 | coroutine_t *co = get_curr_co_can_null(); 67 | if (co) { 68 | co->is_enable_pthread_hook = stat; 69 | } 70 | } 71 | 72 | class DisablePthreadHook 73 | { 74 | public: 75 | int m_stat; 76 | DisablePthreadHook() 77 | { 78 | m_stat = 0; 79 | disable_pthread_hook_save(&m_stat); 80 | } 81 | 82 | ~DisablePthreadHook() 83 | { 84 | restore_pthread_hook_stat(m_stat); 85 | } 86 | }; 87 | 88 | 89 | struct pthread_mgr_t; 90 | 91 | void free_pthread_mgr(pthread_mgr_t*); 92 | } 93 | 94 | #endif /* end of include guard */ 95 | -------------------------------------------------------------------------------- /core/src/co_pool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: co_pool.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月21日 04时12分06秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "../../base/list.h" 20 | #include "co_pool.h" 21 | 22 | namespace conet 23 | { 24 | 25 | void init_co_pool(co_pool_t *pool, int max_num) 26 | { 27 | INIT_LIST_HEAD(&pool->free_list); 28 | INIT_LIST_HEAD(&pool->used_list); 29 | pool->total_num = 0; 30 | pool->max_num = max_num; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/src/co_swap_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: co_swap_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月30日 06时59分08秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "conet_all.h" 20 | #include "gflags/gflags.h" 21 | #include "../base/module.h" 22 | 23 | using namespace conet; 24 | 25 | namespace conet 26 | { 27 | void print_stacktrace(coroutine_t *co, int fd, int baddr); 28 | } 29 | 30 | coroutine_t *g_co = NULL; 31 | 32 | int t(void *arg) 33 | { 34 | conet::print_stacktrace(g_co, 2, 1); 35 | uint64_t i = 0; 36 | do { 37 | i = (uint64_t)yield(); 38 | } while (i >0); 39 | return 0; 40 | } 41 | 42 | int t2(void * arg) 43 | { 44 | uint64_t num = (uint64_t)(arg); 45 | coroutine_t *co = conet::alloc_coroutine(&t, NULL); 46 | for(uint64_t i = (uint64_t)num; i > 0; --i) 47 | { 48 | resume(co, (void *)(i)); 49 | } 50 | resume(co, NULL); 51 | conet::free_coroutine(co); 52 | return 0; 53 | } 54 | 55 | DEFINE_int32(num, 1000000, "swap num"); 56 | 57 | int main(int argc, char * argv[]) 58 | { 59 | InitAllModule(argc, argv); 60 | conet::init_conet_global_env(); 61 | conet::init_conet_env(); 62 | g_co = conet::alloc_coroutine(&t2, (void *)(uint64_t)FLAGS_num); 63 | resume(g_co, NULL); 64 | //conet::print_stacktrace(g_co, 2); 65 | conet::wait(g_co); 66 | conet::free_coroutine(g_co); 67 | return 0; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /core/src/common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: common.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/24/2015 02:40:12 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "./common.h" 25 | #include "./time_mgr.h" 26 | #include "coroutine_env.h" 27 | #include "fd_ctx.h" 28 | #include "log.h" 29 | namespace conet 30 | { 31 | static int g_cenv_inited = 0; 32 | int init_conet_global_env() 33 | { 34 | int ret = 0; 35 | if (g_cenv_inited) { 36 | return 0; 37 | } 38 | g_cenv_inited = 1; 39 | ret = time_mgr_t::instance().start(); 40 | if (ret) { 41 | PLOG_FATAL("init time mgr failed! [ret=", ret, "]"); 42 | return -1; 43 | } 44 | g_coroutine_envs = new coroutine_env_t*[10240000]; 45 | 46 | conet::init_fd_ctx_env(); 47 | return 0; 48 | } 49 | 50 | int free_conet_global_env() 51 | { 52 | int ret = 0; 53 | ret = time_mgr_t::instance().stop(); 54 | if (ret) { 55 | PLOG_FATAL("free time mgr failed! [ret=", ret, "]"); 56 | return -1; 57 | } 58 | delete g_coroutine_envs; 59 | return 0; 60 | } 61 | 62 | uint64_t get_local_tid() 63 | { 64 | static __thread uint64_t tid = 0; 65 | if (tid > 0) return tid; 66 | //pid_t pid = getpid(); 67 | tid = syscall(__NR_gettid); 68 | //tid = tid2-pid; 69 | return tid; 70 | } 71 | 72 | int init_conet_env() 73 | { 74 | if (g_coroutine_env) { 75 | PLOG_INFO("duplicate init coroutine env"); 76 | return 0; 77 | } 78 | uint64_t tid = get_local_tid(); 79 | coroutine_env_t *env = new coroutine_env_t(); 80 | g_coroutine_env = env; 81 | g_coroutine_envs[tid] = env; 82 | env->tw->start(); 83 | return 0; 84 | } 85 | 86 | int free_conet_env() 87 | { 88 | if (NULL == g_coroutine_env) { 89 | //PLOG_FATAL("coroutine env don't init , free is bug!"); 90 | return -1; 91 | } 92 | 93 | uint64_t tid = get_local_tid(); 94 | delete g_coroutine_env; 95 | g_coroutine_env = NULL; 96 | g_coroutine_envs[tid] = NULL; 97 | return 0; 98 | } 99 | 100 | static int init_cg_env=conet::init_conet_global_env(); 101 | static int init_c_env=conet::init_conet_env(); 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /core/src/gc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: gc.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月14日 08时10分32秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include "gc.h" 21 | 22 | namespace conet 23 | { 24 | 25 | void gc_free_all(gc_mgr_t *mgr) 26 | { 27 | list_head * it = NULL, *next = NULL; 28 | list_for_each_safe(it, next, &mgr->alloc_list) 29 | { 30 | gc_block_t * block = container_of(it, gc_block_t, link); 31 | if (block->destructor) { 32 | block->destructor(block->data, block->num); 33 | } 34 | list_del(&block->link); 35 | free(block); 36 | } 37 | } 38 | 39 | void init_gc_mgr(gc_mgr_t *mgr) 40 | { 41 | INIT_LIST_HEAD(&mgr->alloc_list); 42 | } 43 | 44 | void gc_free(void *p) 45 | { 46 | assert(p); 47 | gc_block_t *block = container_of(p, gc_block_t, data); 48 | if (block->destructor) { 49 | block->destructor(block->data, block->num); 50 | } 51 | list_del(&block->link); 52 | free(block); 53 | } 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /core/src/gethostbyname_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: gethostbyname_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月15日 03时44分59秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include 21 | #include "conet_all.h" 22 | #include "gflags/gflags.h" 23 | #include "base/plog.h" 24 | #include "base/module.h" 25 | 26 | #include 27 | 28 | using namespace conet; 29 | 30 | DEFINE_int32(task_num, 10, "query time"); 31 | DEFINE_int32(num, 100, "query time"); 32 | DEFINE_string(name, "www.baidu.com", "resolve host name"); 33 | 34 | coroutine_t *g_co = NULL; 35 | 36 | int g_finish_cnt = 0; 37 | int t(void *arg) 38 | { 39 | for (int i=0; i< FLAGS_num; ++i) 40 | { 41 | hostent * host = gethostbyname(FLAGS_name.c_str()); 42 | if (host) { 43 | PLOG_INFO("host:", host->h_name); 44 | } 45 | else { 46 | PLOG_ERROR("parse ", FLAGS_name, " failed!"); 47 | } 48 | } 49 | ++g_finish_cnt; 50 | return 0; 51 | } 52 | 53 | 54 | 55 | int main(int argc, char * argv[]) 56 | { 57 | InitAllModule(argc, argv); 58 | //conet::init_conet_global_env(); 59 | //conet::init_conet_env(); 60 | 61 | for (int i= 0; i< (int) FLAGS_task_num; ++i) 62 | { 63 | conet::coroutine_t *co = conet::alloc_coroutine(&t, NULL); 64 | conet::set_auto_delete(co); 65 | resume(co, NULL); 66 | } 67 | 68 | while (g_finish_cnt < FLAGS_task_num) { 69 | conet::dispatch(); 70 | } 71 | return 0; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /core/src/malloc_hook.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: malloc_hook.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月20日 11时41分05秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define SYS_FUNC(name) g_sys_##name##_func 24 | #define _(name) SYS_FUNC(name) 25 | 26 | #define HOOK_FUNC_DEF(ret_type, name, proto) \ 27 | typedef ret_type (* name##_pfn_t) proto; \ 28 | name##_pfn_t _(name) = (name##_pfn_t) dlsym(RTLD_NEXT, #name) ; \ 29 | ret_type name proto \ 30 | 31 | #define HOOK_FUNC(name) \ 32 | do { \ 33 | if( !_(name)) { \ 34 | _(name) = (name##_pfn_t) dlsym(RTLD_NEXT,#name); \ 35 | } \ 36 | } while(0) \ 37 | 38 | namespace 39 | { 40 | int64_t __thread g_in_malloc = 0; 41 | 42 | class SetInMallocHelp 43 | { 44 | public: 45 | SetInMallocHelp() 46 | { 47 | //__sync_fetch_and_add(&g_in_malloc, 1); 48 | ++g_in_malloc; 49 | } 50 | 51 | ~SetInMallocHelp() 52 | { 53 | --g_in_malloc; 54 | //__sync_fetch_and_add(&g_in_malloc,-1); 55 | } 56 | }; 57 | 58 | } 59 | 60 | namespace conet 61 | { 62 | 63 | int64_t is_in_malloc() 64 | { 65 | return g_in_malloc; 66 | } 67 | } 68 | 69 | 70 | 71 | 72 | #define DISABLE_CO_HOOK() SetInMallocHelp __set_in_malloc_##__LINE__ 73 | 74 | 75 | HOOK_FUNC_DEF(void*, malloc, (size_t size)) 76 | { 77 | HOOK_FUNC(malloc); 78 | 79 | DISABLE_CO_HOOK(); 80 | return _(malloc)(size); 81 | } 82 | 83 | HOOK_FUNC_DEF(void *, realloc, (void *ptr, size_t size)) 84 | { 85 | HOOK_FUNC(realloc); 86 | DISABLE_CO_HOOK(); 87 | return _(realloc)(ptr, size); 88 | } 89 | 90 | HOOK_FUNC_DEF(void *, memalign, (size_t b, size_t size)) 91 | { 92 | HOOK_FUNC(memalign); 93 | DISABLE_CO_HOOK(); 94 | return _(memalign)(b, size); 95 | } 96 | 97 | HOOK_FUNC_DEF(void , free, (void *ptr)) 98 | { 99 | HOOK_FUNC(free); 100 | DISABLE_CO_HOOK(); 101 | return _(free)(ptr); 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /core/src/swap_context.s: -------------------------------------------------------------------------------- 1 | /* 2 | * Tencent is pleased to support the open source community by making Libco available. 3 | 4 | * Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | .globl coctx_swap 20 | #if !defined( __APPLE__ ) 21 | .type coctx_swap, @function 22 | #endif 23 | coctx_swap: 24 | 25 | #if defined(__i386__) 26 | movl 4(%esp), %eax 27 | movl %esp, 28(%eax) 28 | movl %ebp, 24(%eax) 29 | movl %esi, 20(%eax) 30 | movl %edi, 16(%eax) 31 | movl %edx, 12(%eax) 32 | movl %ecx, 8(%eax) 33 | movl %ebx, 4(%eax) 34 | 35 | 36 | movl 8(%esp), %eax 37 | movl 4(%eax), %ebx 38 | movl 8(%eax), %ecx 39 | movl 12(%eax), %edx 40 | movl 16(%eax), %edi 41 | movl 20(%eax), %esi 42 | movl 24(%eax), %ebp 43 | movl 28(%eax), %esp 44 | 45 | ret 46 | 47 | #elif defined(__x86_64__) 48 | leaq (%rsp),%rax 49 | movq %rax, 104(%rdi) 50 | movq %rbx, 96(%rdi) 51 | movq %rcx, 88(%rdi) 52 | movq %rdx, 80(%rdi) 53 | movq 0(%rax), %rax 54 | movq %rax, 72(%rdi) 55 | movq %rsi, 64(%rdi) 56 | movq %rdi, 56(%rdi) 57 | movq %rbp, 48(%rdi) 58 | movq %r8, 40(%rdi) 59 | movq %r9, 32(%rdi) 60 | movq %r12, 24(%rdi) 61 | movq %r13, 16(%rdi) 62 | movq %r14, 8(%rdi) 63 | movq %r15, (%rdi) 64 | xorq %rax, %rax 65 | 66 | movq 48(%rsi), %rbp 67 | movq 104(%rsi), %rsp 68 | movq (%rsi), %r15 69 | movq 8(%rsi), %r14 70 | movq 16(%rsi), %r13 71 | movq 24(%rsi), %r12 72 | movq 32(%rsi), %r9 73 | movq 40(%rsi), %r8 74 | movq 56(%rsi), %rdi 75 | movq 80(%rsi), %rdx 76 | movq 88(%rsi), %rcx 77 | movq 96(%rsi), %rbx 78 | leaq 8(%rsp), %rsp 79 | pushq 72(%rsi) 80 | 81 | movq 64(%rsi), %rsi 82 | ret 83 | #endif -------------------------------------------------------------------------------- /core/src/time_hook.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: time_hook.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/13/2015 09:09:18 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include "hook_helper.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "time_mgr.h" 26 | #include "network_hook.h" 27 | 28 | HOOK_CPP_FUNC_DEF(int , gettimeofday, (struct timeval *tv, struct timezone *tz)) 29 | { 30 | HOOK_SYS_FUNC(gettimeofday); 31 | timeval *sys_tv = conet::time_mgr_t::instance().gettimeofday_cache; 32 | if (tz != NULL || NULL == sys_tv) { 33 | return _(gettimeofday)(tv, tz); 34 | } 35 | 36 | int ret = 0; 37 | tv->tv_sec = sys_tv->tv_sec; 38 | tv->tv_usec = sys_tv->tv_usec; 39 | return ret; 40 | } 41 | 42 | 43 | HOOK_CPP_FUNC_DEF(time_t, time, (time_t *out)) 44 | { 45 | HOOK_SYS_FUNC(time); 46 | timeval *sys_tv = conet::time_mgr_t::instance().gettimeofday_cache; 47 | if (NULL == sys_tv) 48 | { 49 | return _(time)(out); 50 | } 51 | 52 | if (out) { 53 | *out = sys_tv->tv_sec; 54 | } 55 | return sys_tv->tv_sec; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /core/src/version.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: version.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月22日 17时00分45秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | namespace conet 21 | { 22 | __attribute__((weak)) char version[64] = "conet version 1.0"; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /core/static_var.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: static_var.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/19/2015 02:35:50 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __STATIC_VAR_H__ 20 | #define __STATIC_VAR_H__ 21 | 22 | #include "gc.h" 23 | 24 | namespace conet 25 | { 26 | 27 | void * get_static_var(void *key); 28 | void * set_static_var(void * key, void *val); 29 | 30 | #define CO_DEF_STATIC_VAR(type, name, ...) \ 31 | static int co_static_var_ct_ ## name = 0; \ 32 | type * co_static_var_p_ ## name = (type *) get_static_var(& co_static_var_ct_ ## name); \ 33 | if (co_static_var_p_ ## name == NULL) { \ 34 | co_static_var_p_ ## name = GC_NEW(type, ##__VA_ARGS__); \ 35 | set_static_var(&co_static_var_ct_ ## name, co_static_var_p_ ## name); \ 36 | } \ 37 | type & name = * co_static_var_p_ ## name 38 | 39 | #define CO_DEF_STATIC_PTR(type, name, init_val) \ 40 | static int co_static_var_ct_ ## name = 0; \ 41 | type * name = (type *) get_static_var(& co_static_var_ct_ ## name); \ 42 | if (name == NULL) { \ 43 | name = init_val; \ 44 | set_static_var(&co_static_var_ct_ ## name, name); \ 45 | } \ 46 | 47 | 48 | } 49 | 50 | #endif /* end of include guard */ 51 | -------------------------------------------------------------------------------- /core/time_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: time_mgr.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 03/24/2015 10:08:45 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __TIME_MGR_H_INC__ 20 | #define __TIME_MGR_H_INC__ 21 | #include "base/obj_pool.h" 22 | #include 23 | #include "base/list.h" 24 | #include 25 | 26 | namespace conet 27 | { 28 | 29 | struct timeout_notify_t 30 | { 31 | list_head link_to; 32 | uint64_t __attribute__((aligned(8))) latest_ms; // 最近的超时时间 33 | int __attribute__((aligned(8))) status; // 1 准备入队列, 2 已经入队列, 3准备离队列, 4 离队成功 34 | int event_fd; 35 | 36 | timeout_notify_t() 37 | { 38 | init(); 39 | } 40 | void init () 41 | { 42 | latest_ms = 0; 43 | event_fd = -1; 44 | status = 0; 45 | INIT_LIST_HEAD(&link_to); 46 | } 47 | }; 48 | 49 | struct time_mgr_t 50 | { 51 | int32_t time_resolution; 52 | int timerfd; 53 | pthread_t *tid; 54 | pthread_mutex_t this_mutex; 55 | 56 | // 64bit, 8字节对齐, 一个写, 多个读, 安全 57 | timeval * __attribute__((aligned(8))) gettimeofday_cache; 58 | uint64_t __attribute__((aligned(8))) cur_ms; 59 | uint64_t __attribute__((aligned(8))) in_queue_num; 60 | int64_t __attribute__((aligned(8))) stop_flag; 61 | 62 | ObjPool notify_pool; 63 | 64 | list_head timeout_notify_queue; // 超时通知队列 65 | 66 | 67 | list_head timeout_notify_inqueue; // 入队队列 68 | list_head timeout_notify_dequeue; // 出队队列 69 | 70 | time_mgr_t() 71 | { 72 | timerfd = 0; 73 | stop_flag = 0; 74 | time_resolution = 1; 75 | tid = NULL; 76 | in_queue_num = 0; 77 | cur_ms = 0; 78 | pthread_mutex_init(&this_mutex, NULL); 79 | INIT_LIST_HEAD(&timeout_notify_queue); 80 | INIT_LIST_HEAD(&timeout_notify_inqueue); 81 | INIT_LIST_HEAD(&timeout_notify_dequeue); 82 | } 83 | 84 | static time_mgr_t &instance(); 85 | 86 | 87 | timeout_notify_t *alloc_timeout_notify(); 88 | 89 | void free(timeout_notify_t *); 90 | 91 | void add_to_queue(timeout_notify_t *); 92 | 93 | int start(); 94 | int stop(); 95 | 96 | //private 97 | timeval tvs[100]; 98 | int tvs_pos; 99 | 100 | void * main_proc(); 101 | void update_gettimeofday_cache(); 102 | void do_in_queue(); 103 | void check_timeout(); 104 | void do_dequeue(); 105 | }; 106 | 107 | extern time_mgr_t g_time_mgr; 108 | 109 | inline 110 | time_mgr_t & time_mgr_t::instance() 111 | { 112 | return g_time_mgr; 113 | } 114 | } 115 | 116 | #endif /* end of include guard */ 117 | -------------------------------------------------------------------------------- /core/timewheel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: timewheel.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月06日 06时22分35秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboyeliu 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __TIMEWHEEL_H_INCL__ 20 | #define __TIMEWHEEL_H_INCL__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "base/list.h" 29 | #include "base/time_helper.h" 30 | #include "dispatch.h" 31 | #include "time_mgr.h" 32 | 33 | namespace conet 34 | { 35 | 36 | struct timewheel_t; 37 | 38 | struct timeout_handle_t 39 | { 40 | list_head link_to; 41 | uint64_t timeout; 42 | void (*fn)(void *); 43 | void * arg; 44 | timewheel_t * tw; 45 | int interval; 46 | }; 47 | 48 | void init_timeout_handle(timeout_handle_t * self, void (*fn)(void *), void *arg); 49 | 50 | #define DEFINE_TIMEOUT_HANDLE(name, func, arg1) \ 51 | timeout_handle_t name; \ 52 | init_timeout_handle(&name, func, arg1) 53 | 54 | 55 | struct coroutine_env_t; 56 | struct timewheel_t 57 | { 58 | uint64_t pos; 59 | uint64_t prev_ms; 60 | 61 | struct { 62 | unsigned int enable_notify:1; 63 | }; 64 | 65 | timeout_notify_t *notify; 66 | int event_fd; 67 | uint64_t latest_ms; 68 | 69 | int task_num; 70 | int slot_num; 71 | uint32_t slot_num_mask; 72 | void * co; 73 | int stop_flag; 74 | int timerfd; 75 | int update_timeofday_flag; 76 | struct timeval prev_tv; 77 | list_head *slots; 78 | uint64_t now_ms; 79 | 80 | list_head now_list; 81 | task_t delay_task; 82 | 83 | coroutine_env_t *co_env; 84 | 85 | explicit 86 | timewheel_t(coroutine_env_t *env, int slot_num); 87 | ~timewheel_t(); 88 | 89 | 90 | int check(uint64_t cur_ms); 91 | 92 | int start(); 93 | int stop(int ms); 94 | 95 | bool set_timeout(timeout_handle_t * obj, int timeout); 96 | bool set_interval(timeout_handle_t * obj, int interval); 97 | }; 98 | 99 | 100 | void cancel_timeout(timeout_handle_t *self); 101 | 102 | bool set_timeout(timewheel_t *tw, timeout_handle_t * obj, int timeout); 103 | bool set_interval(timewheel_t *tw, timeout_handle_t * obj, int interval); 104 | 105 | // global timewheel_t 106 | void set_timeout(timeout_handle_t *obj, int timeout /* ms*/); 107 | void set_interval(timeout_handle_t * obj, int interval); 108 | 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /core/wait_id_event.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: wait_id_event.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月03日 19时49分16秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_WAIT_ID_EVENT_H__ 20 | #define __CONET_WAIT_ID_EVENT_H__ 21 | 22 | #include "../../base/incl/int_map.h" 23 | #include "coroutine.h" 24 | #include "timewheel.h" 25 | 26 | namespace conet 27 | { 28 | 29 | struct WaitIdEvent 30 | { 31 | IntMap wait_map; 32 | 33 | void init(int size) 34 | { 35 | wait_map.init(size); 36 | } 37 | 38 | struct Node 39 | { 40 | IntMap::node_type map_node; 41 | uint64_t id; 42 | int timeout; 43 | coroutine_t *co; 44 | timeout_handle_t tm; 45 | void *msg; 46 | }; 47 | 48 | static void timeout_proc(void *arg) 49 | { 50 | Node *node = (Node *)(arg); 51 | node->timeout = 1; 52 | conet::resume(node->co); 53 | } 54 | 55 | // 0 正常, 1 超时, -1 是id 已经存在 56 | int wait(uint64_t id, void **msg, int ms=0) 57 | { 58 | Node node; 59 | node.map_node.init(id); 60 | node.id = id; 61 | node.co = CO_SELF(); 62 | node.timeout = 0; 63 | int ret = this->wait_map.add(&node.map_node); 64 | if (ret) { 65 | return -1; 66 | } 67 | 68 | if (ms > 0) { 69 | init_timeout_handle(&node.tm, &timeout_proc, &node); 70 | set_timeout(&node.tm, ms); 71 | } 72 | conet::yield(); 73 | if (ms >0) { 74 | cancel_timeout(&node.tm); 75 | } 76 | if (node.timeout) { 77 | return 1; 78 | } 79 | 80 | *msg = node.msg; 81 | return 0; 82 | } 83 | 84 | int notify(uint64_t id, void * msg) 85 | { 86 | IntMap::node_type *n1 = this->wait_map.find(id); 87 | 88 | if (NULL == n1 ) { 89 | return -1; 90 | } 91 | 92 | Node *node = container_of(n1, Node, map_node); 93 | node->msg = msg; 94 | conet::resume(node->co); 95 | return 0; 96 | } 97 | }; 98 | 99 | } 100 | 101 | #endif /* end of include guard */ 102 | -------------------------------------------------------------------------------- /core/wait_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: wait_queue.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年09月12日 15时51分00秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef WAIT_QUEUE_H_INCL 19 | #define WAIT_QUEUE_H_INCL 20 | 21 | 22 | #include "base/list.h" 23 | #include "timewheel.h" 24 | 25 | namespace conet 26 | { 27 | 28 | // 等待队列 29 | struct WaitQueue 30 | { 31 | int wait_num; 32 | list_head queue; 33 | 34 | 35 | WaitQueue(); 36 | 37 | ~WaitQueue(); 38 | 39 | // -1 超时, 0 是成功 40 | int wait_on(int ms = -1); 41 | 42 | int wakeup_all(); 43 | 44 | int wakeup_head_n(int num=1); 45 | 46 | int wakeup_head(); 47 | 48 | int wakeup_tail_n(int num=1); 49 | 50 | int wakeup_tail(); 51 | }; 52 | 53 | // 条件等待队列 54 | // 55 | struct CondWaitQueue 56 | { 57 | WaitQueue wait_queue; 58 | 59 | int (*cond_check_func)(void *arg); 60 | void *func_arg; 61 | 62 | int delay_ms; 63 | 64 | int init(int (*func)(void *arg), void *arg, int delay_ms); 65 | 66 | timeout_handle_t tm; //超时控制 67 | 68 | //method 69 | CondWaitQueue(); 70 | 71 | int wait_on(int times=-1); 72 | 73 | int wakeup_all(); 74 | 75 | }; 76 | 77 | } 78 | 79 | #endif /* end of include guard */ 80 | -------------------------------------------------------------------------------- /example/aio_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * ===================================================================================== 4 | * 5 | * Filename: aio_test.cpp 6 | * 7 | * Description: 8 | * 9 | * Version: 1.0 10 | * Created: 2014年06月26日 22时51分50秒 11 | * Revision: none 12 | * Compiler: gcc 13 | * 14 | * Author: YOUR NAME (), 15 | * Organization: 16 | * 17 | * ===================================================================================== 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "core/conet_all.h" 26 | #include "thirdparty/gflags/gflags.h" 27 | #include "base/module.h" 28 | 29 | DEFINE_string(out_file, "2.txt", "output file name"); 30 | 31 | int proc(void *arg) 32 | { 33 | 34 | conet::enable_sys_hook(); 35 | 36 | int ret = 0; 37 | FILE *fp = fopen(FLAGS_out_file.c_str(), "a"); 38 | ret = write(fileno(fp), "hello\n",6); 39 | fprintf(stderr, "pos:%d, out:%d\n", (int)(ftell(fp)), ret); 40 | fputs("hello:\n", fp); 41 | fprintf(stderr, "pos:%d, out:%d\n", (int)(ftell(fp)), ret); 42 | return -1; 43 | } 44 | 45 | int main(int argc, char * argv[]) 46 | { 47 | InitAllModule(argc, argv); 48 | conet::coroutine_t *co = conet::alloc_coroutine(proc, NULL); 49 | conet::resume(co); 50 | while (conet::get_epoll_pend_task_num() >0) { 51 | conet::dispatch(); 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /example/echo_cli.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: echo_cli.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月11日 08时16分30秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include "base/net_tool.h" 22 | 23 | 24 | int main(int argc, char const* argv[]) 25 | { 26 | if (argc < 3) { 27 | fprintf(stderr, "usage:%s ip port\n", argv[0]); 28 | return 0; 29 | } 30 | char const * ip = argv[1]; 31 | int port = atoi(argv[2]); 32 | 33 | int ret = 0; 34 | int fd = 0; 35 | fd = conet::connect_to(ip, port); 36 | conet::set_none_block(fd, false); 37 | char *line= NULL; 38 | size_t len = 0; 39 | char rbuff[1024]; 40 | while( (ret = getline(&line, &len, stdin)) >= 0) { 41 | if (ret == 0) continue; 42 | ret = send(fd, line, ret, 0); 43 | if (ret <= 0) break; 44 | ret = recv(fd, rbuff, 1024, 0); 45 | if (ret <=0) break; 46 | send(1, rbuff, ret, 0); 47 | } 48 | close(fd); 49 | free(line); 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /example/echo_rpc.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option cc_enable_arenas=true; 3 | 4 | message EchoReq 5 | { 6 | optional string msg = 1; // request message 7 | } 8 | 9 | message EchoResp 10 | { 11 | optional string msg = 1; 12 | } 13 | -------------------------------------------------------------------------------- /example/echo_rpc_cli.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: echo_cli.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月11日 08时16分30秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include "example/echo_rpc.pb.h" 22 | #include "svrkit/rpc_pb_client.h" 23 | #include "thirdparty/gflags/gflags.h" 24 | #include "base/net_tool.h" 25 | #include "base/module.h" 26 | 27 | DEFINE_string(server_addr, "127.0.0.1:12314", "server address"); 28 | 29 | int main(int argc, char * argv[]) 30 | { 31 | 32 | InitAllModule(argc, argv); 33 | 34 | conet::IpListLB lb; 35 | lb.init(FLAGS_server_addr); 36 | int ret = 0; 37 | char *line= NULL; 38 | size_t len = 0; 39 | while( (ret = getline(&line, &len, stdin)) >= 0) { 40 | if (ret == 0) continue; 41 | EchoReq req; 42 | EchoResp resp; 43 | req.set_msg(std::string(line, ret)); 44 | int retcode = 0; 45 | ret = conet::rpc_pb_call(lb, "echo", &req, &resp, &retcode, NULL); 46 | printf("ret:%d, retcode:%d, response:%s\n", ret, retcode, resp.msg().c_str()); 47 | } 48 | free(line); 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /example/echo_rpc_cli_co2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: echo_rpc_cli_co.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年07月08日 19时20分08秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include "example/echo_rpc.pb.h" 23 | #include "svrkit/rpc_pb_client.h" 24 | #include "thirdparty/gflags/gflags.h" 25 | #include "base/plog.h" 26 | #include "core/conet_all.h" 27 | 28 | #include "base/net_tool.h" 29 | #include "base/defer.h" 30 | #include "base/module.h" 31 | 32 | 33 | DEFINE_string(server_addr, "127.0.0.1:12314", "server address"); 34 | DEFINE_int32(task_num, 10, "concurrent task num"); 35 | DEFINE_int32(send_num, 100000, "send num per task"); 36 | struct task_t 37 | { 38 | conet::IpListLB *lb; 39 | conet::coroutine_t *co; 40 | }; 41 | 42 | int g_finish_task_num=0; 43 | int proc_send(void *arg) 44 | { 45 | conet::enable_sys_hook(); 46 | conet::enable_pthread_hook(); 47 | task_t *task = (task_t *)(arg); 48 | 49 | int ret = 0; 50 | uint64_t cmd_id = 3; 51 | std::string errmsg; 52 | int send_num = FLAGS_send_num; 53 | int fd = task->lb->get(); 54 | for (int i=0; ilb->get(); 63 | continue; 64 | } 65 | 66 | if (retcode) { 67 | close(fd); 68 | fd = task->lb->get(); 69 | PLOG_ERROR((retcode, errmsg)); 70 | } 71 | } 72 | if (fd >= 0) close(fd); 73 | ++g_finish_task_num; 74 | return 0; 75 | } 76 | 77 | task_t *tasks = NULL; 78 | int main(int argc, char * argv[]) 79 | { 80 | InitAllModule(argc, argv); 81 | 82 | conet::IpListLB lb; 83 | lb.init(FLAGS_server_addr); 84 | 85 | //conet::init_conet_global_env(); 86 | CONET_DEFER({ 87 | conet::free_conet_global_env(); 88 | }); 89 | 90 | tasks = new task_t[FLAGS_task_num]; 91 | for (int i=0; i 19 | #include 20 | #include 21 | #include "base/net_tool.h" 22 | #include "example/echo_rpc.pb.h" 23 | #include "svrkit/rpc_pb_client.h" 24 | #include "thirdparty/gflags/gflags.h" 25 | #include "base/net_tool.h" 26 | #include "base/ip_list.h" 27 | #include "base/plog.h" 28 | #include "base/module.h" 29 | 30 | DEFINE_string(server_addr, "127.0.0.1:12314", "server address"); 31 | 32 | using namespace conet; 33 | 34 | int main(int argc, char * argv[]) 35 | { 36 | 37 | InitAllModule(argc, argv); 38 | std::vector ip_list; 39 | parse_ip_list(FLAGS_server_addr, &ip_list); 40 | 41 | if (ip_list.size() <=0) { 42 | PLOG_ERROR("error server addr:", FLAGS_server_addr); 43 | return 1; 44 | } 45 | 46 | int ret = 0; 47 | int fd = create_udp_socket(); 48 | struct sockaddr_in addr; 49 | set_addr(&addr, ip_list[0].ip.c_str(), ip_list[0].port); 50 | ret = connect(fd, (struct sockaddr*)&addr,sizeof(addr)); 51 | char *line= NULL; 52 | size_t len = 0; 53 | while( (ret = getline(&line, &len, stdin)) >= 0) { 54 | if (ret == 0) continue; 55 | EchoReq req; 56 | EchoResp resp; 57 | req.set_msg(std::string(line, ret)); 58 | int retcode = 0; 59 | ret = conet::rpc_pb_udp_call(fd, "echo", &req, &resp, &retcode, NULL); 60 | printf("ret:%d, retcode:%d, response:%s\n", ret, retcode, resp.msg().c_str()); 61 | } 62 | close(fd); 63 | free(line); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /example/echo_rpc_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: echo_rpc_server.cpp 5 | * 6 | * Description 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月25日 10时08分26秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "svrkit/rpc_pb_server.h" 24 | #include "example/echo_rpc.pb.h" 25 | #include "thirdparty/gflags/gflags.h" 26 | #include "base/plog.h" 27 | #include "svrkit/server_common.h" 28 | #include "base/module.h" 29 | 30 | using namespace conet; 31 | 32 | class EchoServer 33 | { 34 | public: 35 | EchoServer() { 36 | m_cur_cnt = 0; 37 | m_prev_cnt = 0; 38 | } 39 | 40 | std::string m_pre; 41 | int m_cur_cnt; 42 | int m_prev_cnt; 43 | 44 | int proc_echo_impl(rpc_pb_ctx_t *ctx, 45 | EchoReq *req, EchoResp *resp, std::string *errmsg) 46 | { 47 | 48 | //resp->set_msg(m_pre + req->msg()); 49 | resp->set_msg(req->msg()); 50 | m_cur_cnt++; 51 | //LOG(ERROR)<GetDescriptor()->DebugString(); 52 | //LOG(INFO)<msg(); 53 | return 0; 54 | } 55 | 56 | }; 57 | 58 | EchoServer echo_server; 59 | 60 | DEFINE_MODULE(echo_server) 61 | { 62 | std::string a; 63 | echo_server.m_pre="fuck:"; 64 | CO_RUN((a), { 65 | while(!conet::get_server_stop_flag()) { 66 | int cnt = echo_server.m_cur_cnt - echo_server.m_prev_cnt; 67 | echo_server.m_prev_cnt = echo_server.m_cur_cnt; 68 | if (cnt >0) { 69 | PLOG_INFO("qps:", cnt); 70 | } 71 | sleep(1); 72 | } 73 | }); 74 | return 0; 75 | } 76 | 77 | REGISTRY_RPC_PB_FUNC(1, "echo", &EchoServer::proc_echo_impl, &echo_server); 78 | 79 | int proc_echo_impl(void *arg, rpc_pb_ctx_t *ctx, 80 | EchoReq *req, EchoResp *resp, std::string *errmsg) 81 | { 82 | resp->set_msg(req->msg()); 83 | PLOG_INFO(req->msg()); 84 | return 0; 85 | } 86 | 87 | REGISTRY_RPC_PB_FUNC(2, "echo2", &proc_echo_impl, NULL); 88 | 89 | int proc_test_impl(void *arg, rpc_pb_ctx_t *ctx, 90 | void *req, void *resp, std::string *errmsg) 91 | { 92 | return 0; 93 | } 94 | 95 | REGISTRY_RPC_PB_FUNC(3, "test", &proc_test_impl, NULL); 96 | -------------------------------------------------------------------------------- /example/http_bench.sh: -------------------------------------------------------------------------------- 1 | wrk --pin-cpus -H 'Host: 127.0.0.1' -H 'Accept: text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7' -H 'Connection: keep-alive' --latency -d 15 -c 100 --timeout 8 -t 4 http://127.0.0.1:8080/hello 2 | -------------------------------------------------------------------------------- /example/tsung.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gcc_env.sh: -------------------------------------------------------------------------------- 1 | export CPP="gcc -E" 2 | export CC="gcc" 3 | export CXX="g++" 4 | export LD="g++" 5 | -------------------------------------------------------------------------------- /get_deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "get thirdparty" 3 | if [[ ! -d thirdparty ]] 4 | then 5 | git clone https://github.com/piboye/thirdparty thirdparty 6 | fi 7 | 8 | echo "get blade" 9 | which blade 10 | if (( $? != 0 )) 11 | then 12 | git clone --branch 1.1.3 https://github.com/chen3feng/typhoon-blade.git blade/ 13 | (cd blade; ./install) 14 | . ~/bin/bladefunctions 15 | pip2 install scons 16 | fi 17 | 18 | cp -r tools/* ~/bin/ 19 | 20 | exit 21 | 22 | 23 | echo "get gtest" 24 | if [[ ! -d gtest ]] 25 | then 26 | svn checkout http://googletest.googlecode.com/svn/trunk/ gtest 27 | (cd gtest; cmake -f CMakeLists.txt) 28 | #else 29 | #(cd gtest; svn update) 30 | fi 31 | cp GTEST_BUILD gtest/BUILD 32 | cp -fr gtest/include/gtest include/ 33 | 34 | echo "get gmock" 35 | if [[ ! -d gmock ]] 36 | then 37 | svn checkout http://googlemock.googlecode.com/svn/trunk/ gmock 38 | (cd gmock; cmake -f CMakeLists.txt; make) 39 | #else 40 | #(cd gmock; svn update) 41 | fi 42 | cp GMOCK_BUILD gmock/BUILD 43 | cp -fr gmock/include/gmock include/ 44 | cp -fr gmock/gtest/include/gtest include/ 45 | 46 | echo "get glog" 47 | if [[ ! -d glog ]] 48 | then 49 | svn checkout http://google-glog.googlecode.com/svn/trunk/ glog 50 | (cd glog; ./configure) 51 | #else 52 | #(cd glog; svn update) 53 | fi 54 | cp GLOG_BUILD glog/BUILD 55 | cp -r glog/src/glog include/ 56 | 57 | 58 | echo "get gflags" 59 | if [[ ! -d gflags ]] 60 | then 61 | git clone https://code.google.com/p/gflags/ 62 | (cd gflags; cmake -f CMakeLists.txt) 63 | #else 64 | #(cd glog; svn update) 65 | fi 66 | cp GFLAGS_BUILD gflags/BUILD 67 | cp -r gflags/include/gflags include/ 68 | 69 | -------------------------------------------------------------------------------- /qjs/BUILD: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | cc_library( 4 | name = 'qjs', 5 | srcs = [ 6 | 'quickjs-libc.c', 7 | 'cutils.c', 8 | 'quickjs.c', 9 | 'libregexp.c', 10 | 'libunicode.c', 11 | 'libbf.c' 12 | ], 13 | 14 | incs= [ 15 | "./", 16 | ], 17 | 18 | deps=[ 19 | ], 20 | 21 | extra_cppflags=['-Wno-error', "-Wno-array-bounds", "-Wno-format-truncation"], 22 | defs=['_GNU_SOURCE', 'CONFIG_BIGNUM', 'CONFIG_CHECK_JSVALUE', 'CONFIG_VERSION=\\"_2021-03-27\\"'], 23 | 24 | export_incs=["./"], 25 | warning = 'no', 26 | link_all_symbols = True, 27 | #export_dynamic = True, 28 | ); 29 | -------------------------------------------------------------------------------- /qjs/LICENSE: -------------------------------------------------------------------------------- 1 | QuickJS Javascript Engine 2 | 3 | Copyright (c) 2017-2021 Fabrice Bellard 4 | Copyright (c) 2017-2021 Charlie Gordon 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /qjs/examples/fib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | 26 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 27 | 28 | static int fib(int n) 29 | { 30 | if (n <= 0) 31 | return 0; 32 | else if (n == 1) 33 | return 1; 34 | else 35 | return fib(n - 1) + fib(n - 2); 36 | } 37 | 38 | static JSValue js_fib(JSContext *ctx, JSValueConst this_val, 39 | int argc, JSValueConst *argv) 40 | { 41 | int n, res; 42 | if (JS_ToInt32(ctx, &n, argv[0])) 43 | return JS_EXCEPTION; 44 | res = fib(n); 45 | return JS_NewInt32(ctx, res); 46 | } 47 | 48 | static const JSCFunctionListEntry js_fib_funcs[] = { 49 | JS_CFUNC_DEF("fib", 1, js_fib ), 50 | }; 51 | 52 | static int js_fib_init(JSContext *ctx, JSModuleDef *m) 53 | { 54 | return JS_SetModuleExportList(ctx, m, js_fib_funcs, 55 | countof(js_fib_funcs)); 56 | } 57 | 58 | #ifdef JS_SHARED_LIBRARY 59 | #define JS_INIT_MODULE js_init_module 60 | #else 61 | #define JS_INIT_MODULE js_init_module_fib 62 | #endif 63 | 64 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 65 | { 66 | JSModuleDef *m; 67 | m = JS_NewCModule(ctx, module_name, js_fib_init); 68 | if (!m) 69 | return NULL; 70 | JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs)); 71 | return m; 72 | } 73 | -------------------------------------------------------------------------------- /qjs/examples/fib_module.js: -------------------------------------------------------------------------------- 1 | /* fib module */ 2 | export function fib(n) 3 | { 4 | if (n <= 0) 5 | return 0; 6 | else if (n == 1) 7 | return 1; 8 | else 9 | return fib(n - 1) + fib(n - 2); 10 | } 11 | -------------------------------------------------------------------------------- /qjs/examples/hello.js: -------------------------------------------------------------------------------- 1 | console.log("Hello World"); 2 | -------------------------------------------------------------------------------- /qjs/examples/hello_module.js: -------------------------------------------------------------------------------- 1 | /* example of JS module */ 2 | 3 | import { fib } from "./fib_module.js"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /qjs/examples/pi_bigdecimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigdecimal type 3 | * (decimal floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' digits */ 8 | function calc_pi(prec) { 9 | const CHUD_A = 13591409m; 10 | const CHUD_B = 545140134m; 11 | const CHUD_C = 640320m; 12 | const CHUD_C3 = 10939058860032000m; /* C^3/24 */ 13 | const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1; 18 | if (a == (b - 1n)) { 19 | b1 = BigDecimal(b); 20 | G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m); 21 | P = G * (CHUD_B * b1 + CHUD_A); 22 | if (b & 1n) 23 | P = -P; 24 | G = G; 25 | Q = b1 * b1 * b1 * CHUD_C3; 26 | } else { 27 | c = (a + b) >> 1n; 28 | [P1, Q1, G1] = chud_bs(a, c, true); 29 | [P2, Q2, G2] = chud_bs(c, b, need_G); 30 | P = P1 * Q2 + P2 * G1; 31 | Q = Q1 * Q2; 32 | if (need_G) 33 | G = G1 * G2; 34 | else 35 | G = 0m; 36 | } 37 | return [P, Q, G]; 38 | } 39 | 40 | var n, P, Q, G; 41 | /* number of serie terms */ 42 | n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n; 43 | [P, Q, G] = chud_bs(0n, n, false); 44 | Q = BigDecimal.div(Q, (P + Q * CHUD_A), 45 | { roundingMode: "half-even", 46 | maximumSignificantDigits: prec }); 47 | G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C, 48 | { roundingMode: "half-even", 49 | maximumSignificantDigits: prec }); 50 | return Q * G; 51 | } 52 | 53 | (function() { 54 | var r, n_digits, n_bits; 55 | if (typeof scriptArgs != "undefined") { 56 | if (scriptArgs.length < 2) { 57 | print("usage: pi n_digits"); 58 | return; 59 | } 60 | n_digits = scriptArgs[1] | 0; 61 | } else { 62 | n_digits = 1000; 63 | } 64 | /* we add more digits to reduce the probability of bad rounding for 65 | the last digits */ 66 | r = calc_pi(n_digits + 20); 67 | print(r.toFixed(n_digits, "down")); 68 | })(); 69 | -------------------------------------------------------------------------------- /qjs/examples/pi_bigfloat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigfloat type 3 | * (binary floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' bits */ 8 | function calc_pi() { 9 | const CHUD_A = 13591409n; 10 | const CHUD_B = 545140134n; 11 | const CHUD_C = 640320n; 12 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 13 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 18 | if (a == (b - 1n)) { 19 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 20 | P = BigFloat(G * (CHUD_B * b + CHUD_A)); 21 | if (b & 1n) 22 | P = -P; 23 | G = BigFloat(G); 24 | Q = BigFloat(b * b * b * CHUD_C3); 25 | } else { 26 | c = (a + b) >> 1n; 27 | [P1, Q1, G1] = chud_bs(a, c, true); 28 | [P2, Q2, G2] = chud_bs(c, b, need_G); 29 | P = P1 * Q2 + P2 * G1; 30 | Q = Q1 * Q2; 31 | if (need_G) 32 | G = G1 * G2; 33 | else 34 | G = 0l; 35 | } 36 | return [P, Q, G]; 37 | } 38 | 39 | var n, P, Q, G; 40 | /* number of serie terms */ 41 | n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n; 42 | [P, Q, G] = chud_bs(0n, n, false); 43 | Q = Q / (P + Q * BigFloat(CHUD_A)); 44 | G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C)); 45 | return Q * G; 46 | } 47 | 48 | (function() { 49 | var r, n_digits, n_bits; 50 | if (typeof scriptArgs != "undefined") { 51 | if (scriptArgs.length < 2) { 52 | print("usage: pi n_digits"); 53 | return; 54 | } 55 | n_digits = scriptArgs[1]; 56 | } else { 57 | n_digits = 1000; 58 | } 59 | n_bits = Math.ceil(n_digits * Math.log2(10)); 60 | /* we add more bits to reduce the probability of bad rounding for 61 | the last digits */ 62 | BigFloatEnv.setPrec( () => { 63 | r = calc_pi(); 64 | print(r.toFixed(n_digits, BigFloatEnv.RNDZ)); 65 | }, n_bits + 32); 66 | })(); 67 | -------------------------------------------------------------------------------- /qjs/examples/test_fib.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | 3 | import { fib } from "./fib.so"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /qjs/examples/test_point.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | import { Point } from "./point.so"; 3 | 4 | function assert(b, str) 5 | { 6 | if (b) { 7 | return; 8 | } else { 9 | throw Error("assertion failed: " + str); 10 | } 11 | } 12 | 13 | class ColorPoint extends Point { 14 | constructor(x, y, color) { 15 | super(x, y); 16 | this.color = color; 17 | } 18 | get_color() { 19 | return this.color; 20 | } 21 | }; 22 | 23 | function main() 24 | { 25 | var pt, pt2; 26 | 27 | pt = new Point(2, 3); 28 | assert(pt.x === 2); 29 | assert(pt.y === 3); 30 | pt.x = 4; 31 | assert(pt.x === 4); 32 | assert(pt.norm() == 5); 33 | 34 | pt2 = new ColorPoint(2, 3, 0xffffff); 35 | assert(pt2.x === 2); 36 | assert(pt2.color === 0xffffff); 37 | assert(pt2.get_color() === 0xffffff); 38 | } 39 | 40 | main(); 41 | -------------------------------------------------------------------------------- /qjs/libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character 54 | position */ 55 | DEF(prev, 1) /* go to the previous char */ 56 | DEF(simple_greedy_quant, 17) 57 | 58 | #endif /* DEF */ 59 | -------------------------------------------------------------------------------- /qjs/quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | void js_std_init_handlers(JSRuntime *rt); 41 | void js_std_free_handlers(JSRuntime *rt); 42 | void js_std_dump_error(JSContext *ctx); 43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 45 | JS_BOOL use_realpath, JS_BOOL is_main); 46 | JSModuleDef *js_module_loader(JSContext *ctx, 47 | const char *module_name, void *opaque); 48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 49 | int flags); 50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 51 | JSValueConst reason, 52 | JS_BOOL is_handled, void *opaque); 53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 54 | 55 | #ifdef __cplusplus 56 | } /* extern "C" { */ 57 | #endif 58 | 59 | #endif /* QUICKJS_LIBC_H */ 60 | -------------------------------------------------------------------------------- /qjs/readme.txt: -------------------------------------------------------------------------------- 1 | The main documentation is in doc/quickjs.pdf or doc/quickjs.html. 2 | -------------------------------------------------------------------------------- /qjs/test262o_errors.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piboye/conet/fd61a3496bbf8c890de31c83d1b54a7189bf7f2e/qjs/test262o_errors.txt -------------------------------------------------------------------------------- /qjs/tests/test262.patch: -------------------------------------------------------------------------------- 1 | diff --git a/harness/atomicsHelper.js b/harness/atomicsHelper.js 2 | index 9c1217351e..3c24755558 100644 3 | --- a/harness/atomicsHelper.js 4 | +++ b/harness/atomicsHelper.js 5 | @@ -227,10 +227,14 @@ $262.agent.waitUntil = function(typedArray, index, expected) { 6 | * } 7 | */ 8 | $262.agent.timeouts = { 9 | - yield: 100, 10 | - small: 200, 11 | - long: 1000, 12 | - huge: 10000, 13 | +// yield: 100, 14 | +// small: 200, 15 | +// long: 1000, 16 | +// huge: 10000, 17 | + yield: 20, 18 | + small: 20, 19 | + long: 100, 20 | + huge: 1000, 21 | }; 22 | 23 | /** 24 | diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js 25 | index be7039fda0..7b38abf8df 100644 26 | --- a/harness/regExpUtils.js 27 | +++ b/harness/regExpUtils.js 28 | @@ -6,24 +6,27 @@ description: | 29 | defines: [buildString, testPropertyEscapes, matchValidator] 30 | ---*/ 31 | 32 | +if ($262 && typeof $262.codePointRange === "function") { 33 | + /* use C function to build the codePointRange (much faster with 34 | + slow JS engines) */ 35 | + codePointRange = $262.codePointRange; 36 | +} else { 37 | + codePointRange = function codePointRange(start, end) { 38 | + const codePoints = []; 39 | + let length = 0; 40 | + for (codePoint = start; codePoint < end; codePoint++) { 41 | + codePoints[length++] = codePoint; 42 | + } 43 | + return String.fromCodePoint.apply(null, codePoints); 44 | + } 45 | +} 46 | + 47 | function buildString({ loneCodePoints, ranges }) { 48 | - const CHUNK_SIZE = 10000; 49 | - let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); 50 | - for (let i = 0; i < ranges.length; i++) { 51 | - const range = ranges[i]; 52 | - const start = range[0]; 53 | - const end = range[1]; 54 | - const codePoints = []; 55 | - for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { 56 | - codePoints[length++] = codePoint; 57 | - if (length === CHUNK_SIZE) { 58 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 59 | - codePoints.length = length = 0; 60 | - } 61 | + let result = String.fromCodePoint.apply(null, loneCodePoints); 62 | + for (const [start, end] of ranges) { 63 | + result += codePointRange(start, end + 1); 64 | } 65 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 66 | - } 67 | - return result; 68 | + return result; 69 | } 70 | 71 | function testPropertyEscapes(regex, string, expression) { 72 | -------------------------------------------------------------------------------- /qjs/tests/test_worker.js: -------------------------------------------------------------------------------- 1 | /* os.Worker API test */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | function assert(actual, expected, message) { 6 | if (arguments.length == 1) 7 | expected = true; 8 | 9 | if (actual === expected) 10 | return; 11 | 12 | if (actual !== null && expected !== null 13 | && typeof actual == 'object' && typeof expected == 'object' 14 | && actual.toString() === expected.toString()) 15 | return; 16 | 17 | throw Error("assertion failed: got |" + actual + "|" + 18 | ", expected |" + expected + "|" + 19 | (message ? " (" + message + ")" : "")); 20 | } 21 | 22 | var worker; 23 | 24 | function test_worker() 25 | { 26 | var counter; 27 | 28 | worker = new os.Worker("./test_worker_module.js"); 29 | 30 | counter = 0; 31 | worker.onmessage = function (e) { 32 | var ev = e.data; 33 | // print("recv", JSON.stringify(ev)); 34 | switch(ev.type) { 35 | case "num": 36 | assert(ev.num, counter); 37 | counter++; 38 | if (counter == 10) { 39 | /* test SharedArrayBuffer modification */ 40 | let sab = new SharedArrayBuffer(10); 41 | let buf = new Uint8Array(sab); 42 | worker.postMessage({ type: "sab", buf: buf }); 43 | } 44 | break; 45 | case "sab_done": 46 | { 47 | let buf = ev.buf; 48 | /* check that the SharedArrayBuffer was modified */ 49 | assert(buf[2], 10); 50 | worker.postMessage({ type: "abort" }); 51 | } 52 | break; 53 | case "done": 54 | /* terminate */ 55 | worker.onmessage = null; 56 | break; 57 | } 58 | }; 59 | } 60 | 61 | 62 | test_worker(); 63 | -------------------------------------------------------------------------------- /qjs/tests/test_worker_module.js: -------------------------------------------------------------------------------- 1 | /* Worker code for test_worker.js */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | var parent = os.Worker.parent; 6 | 7 | function handle_msg(e) { 8 | var ev = e.data; 9 | // print("child_recv", JSON.stringify(ev)); 10 | switch(ev.type) { 11 | case "abort": 12 | parent.postMessage({ type: "done" }); 13 | break; 14 | case "sab": 15 | /* modify the SharedArrayBuffer */ 16 | ev.buf[2] = 10; 17 | parent.postMessage({ type: "sab_done", buf: ev.buf }); 18 | break; 19 | } 20 | } 21 | 22 | function worker_main() { 23 | var i; 24 | 25 | parent.onmessage = handle_msg; 26 | for(i = 0; i < 10; i++) { 27 | parent.postMessage({ type: "num", num: i }); 28 | } 29 | } 30 | 31 | worker_main(); 32 | -------------------------------------------------------------------------------- /qjs/unicode_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | url="ftp://ftp.unicode.org/Public/14.0.0/ucd" 5 | emoji_url="${url}/emoji/emoji-data.txt" 6 | 7 | files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \ 8 | SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \ 9 | UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \ 10 | PropertyValueAliases.txt" 11 | 12 | mkdir -p unicode 13 | 14 | for f in $files; do 15 | g="${url}/${f}" 16 | wget $g -O unicode/$f 17 | done 18 | 19 | wget $emoji_url -O unicode/emoji-data.txt 20 | -------------------------------------------------------------------------------- /svrkit/channel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: channel.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年03月09日 11时27分02秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_CHANNEL_T_H__ 20 | #define __CONET_CHANNEL_T_H__ 21 | #include "conn_info.h" 22 | #include "core/coroutine.h" 23 | #include "base/list.h" 24 | #include "server_base.h" 25 | #include "base/obj_pool.h" 26 | #include "core/wait_queue.h" 27 | 28 | namespace conet 29 | { 30 | 31 | struct channel_t 32 | { 33 | // data 34 | list_head link_to; 35 | conn_info_t *conn; 36 | server_base_t *server; 37 | int r_fd; 38 | int w_fd; 39 | 40 | struct tx_data_t 41 | { 42 | list_head link_to; 43 | void *data; 44 | int len; 45 | 46 | void (*free_fn)(void *arg, void *data, int len); 47 | void * free_arg; 48 | void init(void *data, int len, 49 | void (*free_fn)(void*arg, void *data, int len) = NULL, 50 | void *arg = NULL 51 | ) 52 | { 53 | INIT_LIST_HEAD(&link_to); 54 | this->data = data; 55 | this->len = len; 56 | this->free_fn = free_fn; 57 | this->free_arg = arg; 58 | } 59 | }; 60 | 61 | // 读缓存 62 | char *read_buff; 63 | size_t read_buff_len; 64 | typedef int(*new_data_cb_t)(void *arg, char const * data, int len); 65 | new_data_cb_t new_data_cb; 66 | void * new_data_arg; 67 | 68 | // 设置新数据回调 69 | int set_new_data_cb( new_data_cb_t cb, void *arg); 70 | 71 | // 发送数据队列 72 | list_head tx_queue; 73 | ObjPool tx_data_pool; 74 | int send_msg(char const *data, int len, 75 | void (*free_fn)(void*arg, void *data, int len) = NULL, 76 | void *arg = NULL 77 | ); 78 | 79 | int to_stop; 80 | int r_stop; 81 | int w_stop; 82 | 83 | // 发送数据等待通知 84 | conet::WaitQueue write_notify; 85 | 86 | int max_pending; 87 | int pending_tx_num; 88 | conet::WaitQueue read_notify; 89 | 90 | conet::WaitQueue exit_notify; 91 | 92 | coroutine_t * r_co; 93 | coroutine_t * w_co; 94 | 95 | // interface: 96 | // 97 | int init(conn_info_t *conn, server_base_t* server); 98 | int start(); 99 | int stop(); 100 | channel_t(); 101 | ~channel_t(); 102 | 103 | // private function 104 | // 105 | static int do_read_co(void *arg); 106 | 107 | static int do_write_co(void *arg); 108 | 109 | }; 110 | 111 | } 112 | 113 | #endif /* end of include guard */ 114 | -------------------------------------------------------------------------------- /svrkit/conn_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: conn_info.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月02日 20时34分19秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_CONN_INFO_H__ 19 | #define __CONET_CONN_INFO_H__ 20 | 21 | #include 22 | #include 23 | 24 | namespace conet 25 | { 26 | 27 | struct coroutine_t; 28 | 29 | struct conn_info_t 30 | { 31 | void * server; 32 | uint32_t ip; 33 | int port; 34 | int fd; 35 | struct sockaddr_in addr; 36 | coroutine_t *co; 37 | void *extend; 38 | 39 | conn_info_t() 40 | { 41 | server = NULL; 42 | fd = -1; 43 | co = NULL; 44 | extend = NULL; 45 | memset(&addr, 0, sizeof(addr)); 46 | } 47 | }; 48 | 49 | } 50 | 51 | #endif /* end of include guard */ 52 | -------------------------------------------------------------------------------- /svrkit/default_server.conf: -------------------------------------------------------------------------------- 1 | { 2 | "server_groups": [{ 3 | "group_name" : "main_group", 4 | "servers" : [{ 5 | "server_name" : "main_server", 6 | "tcp_server" : [ 7 | { 8 | "ip" : "{{ip}}", 9 | "port" : {{port}}, 10 | "duplex" : {{duplex}}, 11 | "enable_http" : 1 12 | }] 13 | }], 14 | "thread_num" : {{thread_num}} 15 | }] 16 | } 17 | -------------------------------------------------------------------------------- /svrkit/rpc_base_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option cc_enable_arenas=true; 3 | package conet_rpc_pb; 4 | 5 | message CmdBase 6 | { 7 | enum TYPE 8 | { 9 | UNKOWN_TYPE=0; 10 | REQUEST_TYPE=1; 11 | RESPONSE_TYPE=2; 12 | }; 13 | 14 | enum ERROR 15 | { 16 | SUCCESS = 0; 17 | ERR_UNSUPPORED_CMD = 1; 18 | ERR_PARSE_REQ_BODY = 2; 19 | }; 20 | 21 | //请求和响应共用部分 22 | optional uint32 type=1; 23 | optional bytes cmd_name=2; 24 | optional uint64 cmd_id=3; 25 | optional uint64 seq_id=4; 26 | optional bytes body=5; 27 | 28 | //可变部分 29 | optional sint32 ret=6; 30 | optional bytes errmsg=7; 31 | }; 32 | -------------------------------------------------------------------------------- /svrkit/rpc_conf.proto: -------------------------------------------------------------------------------- 1 | package conet; 2 | 3 | message TcpServer 4 | { 5 | optional string ip = 1; 6 | optional int32 port = 2; 7 | optional int32 max_conn_num=3 [default=100000]; 8 | optional int32 enable_http=4 [default=1]; 9 | optional int32 max_pending_num=5 [default=10000]; 10 | optional int32 duplex=6 [default=0]; 11 | } 12 | 13 | message UdpServer 14 | { 15 | optional string ip = 1; 16 | optional int32 port = 2; 17 | optional int32 max_conn_num=3 [default=100000]; 18 | optional int32 max_pending_num=4 [default=10000]; 19 | } 20 | 21 | message HttpServer 22 | { 23 | optional string ip = 1; 24 | optional int32 port = 2; 25 | optional int32 max_conn_num=3 [default=100000]; 26 | optional int32 keepalive = 4 [default=1]; 27 | } 28 | 29 | message RpcServer 30 | { 31 | optional string server_name=1; 32 | repeated TcpServer tcp_server=2; 33 | repeated UdpServer udp_server=3; 34 | repeated HttpServer http_server=4; 35 | optional int32 max_pending_num=5 [default=100000]; 36 | } 37 | 38 | message ServerGroup 39 | { 40 | optional string group_name=1; 41 | repeated RpcServer servers=2; 42 | 43 | // cpu 亲缘性,每个字符串对应一个线程的设置, 不够就回第1个开始重新开始 44 | // ["1,2","3,4", "0"] 45 | repeated string cpu_affinitys=3; 46 | optional int32 thread_num=4 [default = 1]; // 线程数 47 | } 48 | 49 | message ServerConf 50 | { 51 | repeated ServerGroup server_groups = 1; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /svrkit/rpc_pb_client_duplex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rpc_pb_client_duplex.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月23日 06时23分12秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __RPC_PB_CLIENT_DUPLEX_H__ 20 | #define __RPC_PB_CLIENT_DUPLEX_H__ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include "base/net_tool.h" 28 | #include "base/list.h" 29 | #include "base/ip_list.h" 30 | #include "base/int_map.h" 31 | 32 | #include "core/wait_queue.h" 33 | #include "core/conet_all.h" 34 | 35 | #include "svrkit/rpc_base_pb.pb.h" 36 | 37 | 38 | namespace conet 39 | { 40 | 41 | class RpcPbClientDuplex 42 | { 43 | public: 44 | class ReqCtx; 45 | class TcpChannel; 46 | 47 | list_head m_req_queue; 48 | 49 | 50 | CondWaitQueue m_req_wait; 51 | 52 | IntMap m_in_queue; 53 | uint64_t m_seq_id; 54 | int m_req_num; 55 | std::vector m_channels; 56 | 57 | public: 58 | RpcPbClientDuplex(); 59 | ~RpcPbClientDuplex(); 60 | 61 | int init(char const * host_txt); 62 | int stop(); 63 | 64 | uint64_t get_seq_id(); 65 | 66 | int rpc_call( 67 | uint64_t cmd_id, 68 | google::protobuf::Message const * req, 69 | google::protobuf::Message * rsp, 70 | int *retcode, std::string *errmsg, int timeout); 71 | 72 | int rpc_call( 73 | char const *cmd_name, 74 | google::protobuf::Message const * req, 75 | google::protobuf::Message * rsp, 76 | int *retcode, std::string *errmsg, int timeout); 77 | 78 | int rpc_call_base( 79 | ReqCtx &req_ctx, 80 | google::protobuf::Message const * req, 81 | google::protobuf::Message * rsp, 82 | int *retcode, std::string *errmsg, int timeout); 83 | 84 | static int is_send_data(void *arg); 85 | }; 86 | 87 | } 88 | 89 | #endif /* end of include guard */ 90 | -------------------------------------------------------------------------------- /svrkit/rpc_pb_server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: pb_rpbc_server.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月25日 03时18分43秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __PB_RPC_SERVER_H_INC__ 19 | #define __PB_RPC_SERVER_H_INC__ 20 | #include 21 | #include 22 | 23 | #include "rpc_pb_server_base_impl.h" 24 | 25 | #include "http_server.h" 26 | #include "tcp_server.h" 27 | #include "udp_server.h" 28 | #include "../base/obj_pool.h" 29 | #include "../base/net_tool.h" 30 | #include "google/protobuf/message.h" 31 | #include "cmd_base.h" 32 | 33 | namespace conet 34 | { 35 | 36 | struct tcp_server_t; 37 | struct http_server_t; 38 | struct rpc_pb_server_base_t; 39 | 40 | struct rpc_pb_server_t: public server_base_t 41 | { 42 | std::vector m_servers; 43 | 44 | // tcp, udp server, 真正的底层server, 用于 start 45 | std::set m_raw_servers; 46 | 47 | rpc_pb_server_base_t * base_server; 48 | 49 | std::string http_base_path; 50 | obj_pool_t m_packet_stream_pool; 51 | 52 | int max_packet_size; 53 | 54 | list_head channels; 55 | 56 | //异步业务处理协程池 57 | 58 | obj_pool_t worker_pool; 59 | uint64_t async_req_num; 60 | 61 | rpc_pb_server_t(); 62 | 63 | int init(rpc_pb_server_base_t *base_server); 64 | 65 | int add_server(tcp_server_t *tcp_server); 66 | int add_server(udp_server_t *tcp_server); 67 | int add_server(http_server_t *tcp_server); 68 | 69 | int start(); 70 | 71 | virtual int do_stop(); 72 | 73 | virtual ~rpc_pb_server_t(); 74 | 75 | // help function 76 | PacketStream *alloc_packet_stream(); 77 | int send_pb(int fd, cmd_base_t *, google::protobuf::Message *rsp=NULL); 78 | }; 79 | 80 | } 81 | 82 | 83 | #endif /* end of include guard */ 84 | -------------------------------------------------------------------------------- /svrkit/rpc_pb_server_base_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rpc_pb_server_base_impl.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月02日 22时06分29秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __RPC_PB_SERVER_BASE_IMPL_H__ 20 | #define __RPC_PB_SERVER_BASE_IMPL_H__ 21 | 22 | #include "rpc_pb_server_base.h" 23 | #include "http_server.h" 24 | #include "base/str_map.h" 25 | #include "base/int_map.h" 26 | #include "base/ref_str.h" 27 | 28 | namespace conet 29 | { 30 | 31 | struct rpc_pb_server_base_t; 32 | 33 | int rpc_pb_http_call_cb(void *arg, http_ctx_t *ctx, http_request_t * req, http_response_t *resp); 34 | int rpc_pb_call_cb(rpc_pb_cmd_t *self, rpc_pb_ctx_t *ctx, ref_str_t req, google::protobuf::Message **rsp, std::string *errmsg); 35 | 36 | struct rpc_pb_server_base_t 37 | { 38 | StrMap cmd_maps; 39 | CmdIdMap cmd_id_maps; 40 | 41 | rpc_pb_server_base_t(); 42 | rpc_pb_cmd_t * get_rpc_pb_cmd(char const *name, size_t name_len); 43 | rpc_pb_cmd_t * get_rpc_pb_cmd(uint64_t cmd_id); 44 | 45 | int get_global_server_cmd(std::string const & server_name); 46 | 47 | int registry_http_rpc_default_api(http_server_t *http_server, std::string const &base_path); 48 | int registry_rpc_cmd_http_api(http_server_t *http_server, std::string const & method_name, rpc_pb_cmd_t *cmd, std::string const & base_path); 49 | int registry_all_rpc_http_api(http_server_t *http_server, std::string const &base_path); 50 | }; 51 | 52 | 53 | } 54 | #endif /* end of include guard */ 55 | -------------------------------------------------------------------------------- /svrkit/server_base.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: server_base.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月17日 06时10分07秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_SERVER_BASE_H__ 19 | #define __CONET_SERVER_BASE_H__ 20 | 21 | #include 22 | #include 23 | 24 | namespace conet 25 | { 26 | struct server_base_t 27 | { 28 | enum { 29 | SERVER_NOSTART=-1, 30 | SERVER_START=0, 31 | SERVER_RUNNING=1, 32 | SERVER_STOPING=2, 33 | SERVER_STOPED=3, 34 | }; 35 | int to_stop; 36 | 37 | int state; 38 | 39 | std::string m_server_name; 40 | 41 | server_base_t() 42 | { 43 | state = SERVER_NOSTART; 44 | to_stop = 0; 45 | } 46 | 47 | virtual int start()=0; 48 | 49 | virtual int stop() 50 | { 51 | this->to_stop = 1; 52 | if (this->state == SERVER_STOPED || 53 | this->state == SERVER_STOPING) { 54 | return 0; 55 | } 56 | this->state = SERVER_STOPING; 57 | this->do_stop(); 58 | return 0; 59 | } 60 | 61 | virtual int do_stop(){ return 0;}; 62 | 63 | virtual 64 | bool has_stoped() 65 | { 66 | return state == SERVER_STOPED; 67 | } 68 | 69 | virtual ~server_base_t() 70 | { 71 | 72 | } 73 | }; 74 | 75 | 76 | struct server_combine_t :public server_base_t 77 | { 78 | server_base_t * m_main_server; 79 | std::vector m_servers; 80 | 81 | server_combine_t() 82 | { 83 | m_main_server = NULL; 84 | } 85 | 86 | int init(server_base_t * main_server) 87 | { 88 | m_main_server = main_server; 89 | return 0; 90 | } 91 | 92 | int add(server_base_t *server) 93 | { 94 | m_servers.push_back(server); 95 | return 0; 96 | } 97 | 98 | virtual int start() 99 | { 100 | return m_main_server->start(); 101 | } 102 | 103 | virtual int stop() 104 | { 105 | return m_main_server->stop(); 106 | } 107 | 108 | virtual ~server_combine_t() 109 | { 110 | for(size_t i =0; i 19 | #include "server_base.h" 20 | #include "rpc_pb_server.h" 21 | #include "svrkit/rpc_conf.pb.h" 22 | #include 23 | 24 | namespace conet 25 | { 26 | class server_group_t; 27 | class server_worker_t 28 | { 29 | public: 30 | server_worker_t(); 31 | ~server_worker_t(); 32 | 33 | std::vector servers; 34 | server_group_t * server_group; 35 | pthread_t tid; 36 | std::vector rpc_servers; 37 | int stop_flag; 38 | int exit_finsished; 39 | int exit_seconds; 40 | cpu_set_t *cpu_affinity; 41 | 42 | static void* main(void * arg); 43 | int stop(int seconds); 44 | int proc_server_exit(); 45 | ServerGroup conf; 46 | rpc_pb_server_t *build_rpc_server(RpcServer const & conf); 47 | }; 48 | 49 | class server_group_t 50 | { 51 | public: 52 | server_group_t(); 53 | ~server_group_t(); 54 | 55 | int stop_flag; 56 | std::string group_name; 57 | ServerGroup conf_data; 58 | int thread_num; 59 | std::vector cpu_affinitys; 60 | std::vector m_work_pool; 61 | 62 | static server_group_t * build(ServerGroup const &conf); 63 | 64 | int start(); 65 | 66 | int stop(int seconds); 67 | }; 68 | 69 | class ServerContainer 70 | { 71 | public: 72 | std::vector server_groups; 73 | int start(); 74 | int stop(int seconds); 75 | ~ServerContainer(); 76 | }; 77 | 78 | class ServerBuilder 79 | { 80 | public: 81 | static ServerContainer *build(ServerConf const &conf); 82 | }; 83 | 84 | } 85 | -------------------------------------------------------------------------------- /svrkit/server_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: server_common.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年12月12日 07时38分13秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __CONET_SERVER_COMMON_H__ 20 | #define __CONET_SERVER_COMMON_H__ 21 | 22 | #include "../base/ip_list.h" 23 | #include 24 | #include 25 | 26 | namespace conet 27 | { 28 | 29 | int is_thread_mode(); 30 | 31 | int get_listen_fd(char const *ip, int port, int listen_fd); 32 | 33 | int create_listen_fd(ip_port_t const &ip_port); 34 | 35 | int set_server_stop(); 36 | int get_server_stop_flag(); 37 | 38 | typedef void server_fini_func_t(void); 39 | int registry_server_fini_func(server_fini_func_t *func); 40 | int call_server_fini_func(); 41 | 42 | int get_listen_fd_from_pool(char const *ip, int port); 43 | 44 | std::thread && co_thread_run(std::function op); 45 | 46 | #define REG_SERVER_FININSH(func) \ 47 | static int CONET_MACRO_CONCAT(g_registry_fini_, __LINE__) = conet::registry_server_fini_func(func) 48 | } 49 | 50 | 51 | #endif /* end of include guard */ 52 | -------------------------------------------------------------------------------- /svrkit/src/rpc_base_pb_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rpc_base_pb_test.cpp 5 | * 6 | * Description 7 | * 8 | * Version: 1.0 9 | * Created: 2014年11月09日 07时19分11秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include "svrkit/rpc_base_pb.pb.h" 21 | #include "base/pbc.h" 22 | #include "gtest/gtest.h" 23 | 24 | #include "../cmd_base.h" 25 | 26 | using namespace conet; 27 | 28 | TEST(pbc, decode) 29 | { 30 | conet_rpc_pb::CmdBase msg; 31 | msg.set_type(1); 32 | msg.set_cmd_name("abc"); 33 | msg.set_cmd_id(1); 34 | msg.set_seq_id(2); 35 | msg.set_body("abcdef"); 36 | 37 | std::string txt; 38 | msg.SerializeToString(&txt); 39 | 40 | cmd_base_t cmd_base; 41 | cmd_base.init(); 42 | cmd_base.parse(txt.c_str(), (uint32_t) txt.size()); 43 | 44 | ASSERT_EQ(1, (int)cmd_base.type); 45 | 46 | ASSERT_STREQ("abc", ref_str_as_string(&cmd_base.cmd_name).c_str()); 47 | 48 | ASSERT_EQ(1, (int)cmd_base.cmd_id); 49 | 50 | ASSERT_EQ(2, (int)cmd_base.seq_id); 51 | 52 | ASSERT_STREQ("abcdef", ref_str_as_string(&cmd_base.body).c_str()); 53 | 54 | } 55 | 56 | TEST(pbc, encode) 57 | { 58 | 59 | char buff[1024]={0}; 60 | 61 | cmd_base_t cmd_base; 62 | cmd_base.init(); 63 | cmd_base.type = 1; 64 | init_ref_str(&cmd_base.cmd_name, "abc", strlen("abc")); 65 | cmd_base.cmd_id = 1; 66 | cmd_base.seq_id = 2; 67 | init_ref_str(&cmd_base.body, "abcdef", strlen("abcdef")); 68 | 69 | uint32_t out_len = 0; 70 | cmd_base.serialize_to(buff, (uint32_t )sizeof(buff), &out_len); 71 | 72 | conet_rpc_pb::CmdBase msg; 73 | msg.ParseFromArray(buff, out_len); 74 | 75 | ASSERT_EQ(1, (int)msg.type()); 76 | 77 | ASSERT_STREQ("abc", msg.cmd_name().c_str()); 78 | 79 | ASSERT_EQ(1, (int) msg.cmd_id()); 80 | 81 | ASSERT_EQ(2, (int) msg.seq_id()); 82 | 83 | ASSERT_STREQ("abcdef", msg.body().c_str()); 84 | 85 | } 86 | -------------------------------------------------------------------------------- /svrkit/src/rpc_base_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rpc_base_test.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年10月27日 09时56分30秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | 20 | #include "svrkit/rpc_base_pb.pb.h" 21 | #include "gtest/gtest.h" 22 | 23 | TEST(p, a) 24 | { 25 | conet_rpc_pb::CmdBase a, b; 26 | a.set_seq_id(123); 27 | std::string s; 28 | b.SerializeToString(&s); 29 | a.ParseFromString(s); 30 | ASSERT_EQ(0, (int)a.seq_id()); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /svrkit/src/rpc_cmd_base.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rpc_cmd_base.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月10日 15时40分34秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: YOUR NAME (), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "proto/rpc_base.pb.h" 20 | 21 | 22 | -------------------------------------------------------------------------------- /svrkit/src/stat_mgr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: stat_mgr.cpp 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年01月30日 10时59分16秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #include 19 | #include "stat_mgr.h" 20 | #include "base/pb2sqlite.h" 21 | #include "tls.h" 22 | #include "base/plog.h" 23 | #include "base/auto_var.h" 24 | 25 | namespace conet 26 | { 27 | 28 | bool StatMgr::reg(std::string const &name, get_stat_func_t * get_stat) 29 | { 30 | if (m_stat_items.find(name) != m_stat_items.end()) 31 | { 32 | PLOG_ERROR("conflict stat item [name=", name, "]"); 33 | return false; 34 | } 35 | StatItem * item = new StatItem(); 36 | item->name = name; 37 | item->get_func = get_stat; 38 | INIT_LIST_HEAD(&item->link); 39 | list_add_tail(&item->link, &this->m_list); 40 | m_stat_items.insert(std::make_pair(name, item)); 41 | return true; 42 | } 43 | 44 | 45 | bool StatMgr::unreg(std::string const &name) 46 | { 47 | AUTO_VAR(it , = , m_stat_items.find(name)); 48 | if (it == m_stat_items.end()) { 49 | PLOG_ERROR("noexist stat item [name=", name, "]"); 50 | return false; 51 | } 52 | 53 | StatItem *item = it->second; 54 | list_del_init(&item->link); 55 | m_stat_items.erase(it); 56 | return true; 57 | } 58 | 59 | void StatMgr::start(int interval) 60 | { 61 | m_stat_interval = interval; 62 | } 63 | void StatMgr::stop() 64 | { 65 | 66 | } 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /svrkit/stat_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: stat_mgr.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2015年01月30日 10时53分06秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __CONET_STAT_MGR_H__ 19 | #define __CONET_STAT_MGR_H__ 20 | 21 | #include "google/protobuf/message.h" 22 | #include 23 | #include "base/list.h" 24 | #include 25 | 26 | namespace conet 27 | { 28 | typedef google::protobuf::Message *get_stat_func_t(void *); 29 | struct StatItem 30 | { 31 | list_head link; 32 | get_stat_func_t * get_func; 33 | std::string name; 34 | }; 35 | 36 | struct StatMgr 37 | { 38 | list_head m_list; // 统计列表 39 | std::map m_stat_items; 40 | int m_stat_interval; /* 统计间隔, 单位是秒*/ 41 | 42 | // 注册统计 43 | bool reg(std::string const &name, get_stat_func_t *get_stat); 44 | 45 | // 注销统计 46 | bool unreg(std::string const &name); 47 | 48 | void start(int interval/*secnods*/); 49 | void stop(); 50 | }; 51 | } 52 | 53 | #endif /* end of include guard */ 54 | -------------------------------------------------------------------------------- /svrkit/static/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |

25 | Server supported rpc command 26 |

27 |
28 |
29 |
30 |
31 |
32 | 33 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /svrkit/tcp_server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: tcp_server.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 2014年05月11日 07时43分57秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: piboye 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | #ifndef __TCP_SERVER_H_INC__ 19 | #define __TCP_SERVER_H_INC__ 20 | #include 21 | #include 22 | #include 23 | #include "../core/conet_all.h" 24 | #include "../core/co_pool.h" 25 | #include "../base/list.h" 26 | #include "../base/obj_pool.h" 27 | #include "../base/unix_socket_send_fd.h" 28 | #include "conn_info.h" 29 | #include "server_base.h" 30 | 31 | namespace conet 32 | { 33 | 34 | struct coroutine_t; 35 | 36 | struct tcp_server_t: public server_base_t 37 | { 38 | std::string ip; 39 | int port; 40 | int listen_fd; 41 | int cpu_id = -1; 42 | 43 | int exit_wait_ms; 44 | 45 | //主逻辑 46 | coroutine_t *main_co; 47 | 48 | void *extend; 49 | 50 | typedef int (*conn_proc_cb_t)(void *cb_arg, conn_info_t *conn); 51 | 52 | conn_proc_cb_t conn_proc_cb; 53 | void *cb_arg; 54 | 55 | obj_pool_t co_pool; 56 | 57 | ObjPool conn_info_pool; 58 | 59 | struct conf_t 60 | { 61 | int listen_backlog; 62 | int max_packet_size; 63 | uint32_t max_conn_num; 64 | int duplex; 65 | conf_t() 66 | { 67 | listen_backlog = 1024; 68 | max_packet_size = 100*1024; 69 | max_conn_num = 10000; 70 | duplex = 0; 71 | } 72 | } conf; 73 | 74 | struct data_t 75 | { 76 | uint32_t cur_conn_num; 77 | data_t() 78 | { 79 | cur_conn_num=0; 80 | } 81 | } data; 82 | 83 | 84 | UnixSocketSendFd *accept_fd_queue; 85 | 86 | 87 | void set_conn_cb(conn_proc_cb_t cb, void *arg) 88 | { 89 | conn_proc_cb = cb; 90 | cb_arg = arg; 91 | } 92 | 93 | int main_proc_with_fd_queue(); 94 | 95 | int main_proc_help(); 96 | 97 | int conn_proc_help(); 98 | 99 | int main_proc(); 100 | 101 | int init(const char *ip, int port, int listen_fd=-1); 102 | 103 | virtual int start(); 104 | virtual int clean_up(); 105 | 106 | tcp_server_t(); 107 | ~tcp_server_t(); 108 | }; 109 | 110 | } 111 | 112 | #endif /* end of include guard */ 113 | 114 | -------------------------------------------------------------------------------- /tools/code_stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function help() 4 | { 5 | cat <<-EOF 6 | Code stats tools. 7 | Usage code_stats <--options...> 8 | options: 9 | --build BUILD file 10 | --c++ c/c++ code 11 | --html html 12 | --js js code 13 | --llyy lex and yacc 14 | --php php code 15 | --proto proto file 16 | --python python code 17 | --swig swig code 18 | --verbose show verbose detail 19 | --help show this information 20 | EOF 21 | } 22 | 23 | function make_find_option() 24 | { 25 | for type in $@; do 26 | echo -n " -or -name '*.$type'" 27 | done 28 | } 29 | 30 | function code_stats() 31 | { 32 | local optargs 33 | if ! optargs=`getopt -n code_stats --long help,c++,proto,python,php,java,js,llyy,swig,js,html,build,verbose -- -- "$@"`; then 34 | return 1; 35 | fi 36 | verbose="" 37 | find_options="" 38 | #eval set "$optargs" 39 | while [ -n "$1" ]; do 40 | case $1 in 41 | --build) 42 | find_options="$find_options -or -name BUILD" 43 | shift;; 44 | --c++) 45 | find_options="$find_options `make_find_option h c cc cpp hh hpp`" 46 | shift;; 47 | --proto) 48 | find_options="$find_options `make_find_option proto`" 49 | shift;; 50 | --python) 51 | find_options="$find_options `make_find_option py`" 52 | shift;; 53 | --java) 54 | find_options="$find_options `make_find_option java`" 55 | shift;; 56 | --php) 57 | find_options="$find_options `make_find_option php`" 58 | shift;; 59 | --swig) 60 | find_options="$find_options `make_find_option i`" 61 | shift;; 62 | --llyy) 63 | find_options="$find_options `make_find_option l y ll yy`" 64 | shift;; 65 | --js) 66 | find_options="$find_options `make_find_option js`" 67 | shift;; 68 | --html) 69 | find_options="$find_options `make_find_option htm html`" 70 | shift;; 71 | --help) 72 | help 73 | return;; 74 | --verbose) 75 | verbose="yes" 76 | shift;; 77 | --*) 78 | echo "unknown option $1" >&2 79 | shift; 80 | exit;; 81 | *) 82 | break;; 83 | esac 84 | done 85 | 86 | if [ -z "$find_options" ]; then 87 | help 88 | exit 1 89 | fi 90 | find_options="-false "$find_options 91 | if [ -n "$verbose" ]; then 92 | eval find $@ $find_options | xargs wc -l 93 | else 94 | eval find $@ $find_options | xargs wc -l | tail -n1 95 | fi 96 | } 97 | 98 | code_stats "$@" 99 | --------------------------------------------------------------------------------