diff --git a/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp b/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp index 5be2ffe07..69b9593c7 100644 --- a/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp +++ b/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp @@ -22,7 +22,7 @@ class ACL_CPP_API connect_manager virtual ~connect_manager(void); /** - * 初始化所有服务器的连接池,该函数内部调用 set 过程添加每个服务的连接池 + * 初始化所有服务器的连接池,该函数调用 set 过程添加每个服务的连接池 * @param default_addr {const char*} 缺省的服务器地址,如果非空, * 则在查询时优先使用此服务器 * @param addr_list {const char*} 所有服务器列表,可以为空 @@ -40,7 +40,8 @@ class ACL_CPP_API connect_manager /** * 添加服务器的客户端连接池,该函数可以在程序运行时被调用,内部自动加锁 - * @param addr {const char*} 服务器地址(ip:port) + * @param addr {const char*} 服务器地址,格式:ip:port + * 注意:调用本函数时每次仅能添加一个服务器地址,可以循环调用本方法 * @param count {size_t} 连接池数量限制, 如果该值设为 0,则不设置 * 连接池的连接上限 * @param conn_timeout {int} 网络连接时间(秒) @@ -51,15 +52,16 @@ class ACL_CPP_API connect_manager int conn_timeout = 30, int rw_timeout = 30); /** - * 设置连接池失败后重试的时间时间隔(秒),该函数可以在程序运行时被调用,内部自动加锁 + * 设置连接池失败后重试的时间时间隔(秒),该函数可以在程序运行时被 + * 调用,内部自动加锁 * @param n {int} 当该值 <= 0 时,若连接池出现问题则会立即被重试 */ void set_retry_inter(int n); /** * 设置连接池中空闲连接的空闲生存周期 - * @param ttl {time_t} 空闲连接的生存周期,当该值 < 0 则表示空闲连接不过期, - * == 0 时表示立刻过期,> 0 表示空闲该时间段后将被释放 + * @param ttl {time_t} 空闲连接的生存周期,当该值 < 0 则表示空闲连接 + * 不过期,== 0 时表示立刻过期,> 0 表示空闲该时间段后将被释放 */ void set_idle_ttl(time_t ttl); @@ -81,17 +83,17 @@ class ACL_CPP_API connect_manager * @param addr {const char*} redis 服务器地址(ip:port) * @param exclusive {bool} 是否需要互斥访问连接池数组,当需要动态 * 管理连接池集群时,该值应为 true - * @param restore {bool} 当该服务结点被置为不可用时,该参数决定是否自动 - * 将之恢复为可用状态 + * @param restore {bool} 当该服务结点被置为不可用时,该参数决定是否 + * 自动将之恢复为可用状态 * @return {connect_pool*} 返回空表示没有此服务 */ connect_pool* get(const char* addr, bool exclusive = true, bool restore = false); /** - * 从连接池集群中获得一个连接池,该函数采用轮循方式从连接池集合中获取一个 - * 后端服务器的连接池,从而保证了完全的均匀性;该函数内部会自动对连接池管理 - * 队列加锁 + * 从连接池集群中获得一个连接池,该函数采用轮循方式从连接池集合中获取 + * 一个后端服务器的连接池,从而保证了完全的均匀性;该函数内部会自动对 + * 连接池管理队列加锁 * 此外,该函数为虚接口,允许子类实现自己的轮循方式 * @return {connect_pool*} 返回一个连接池,返回指针永远非空 */ @@ -155,18 +157,19 @@ class ACL_CPP_API connect_manager /** * 启动后台非阻塞检测线程检测所有连接池连接状态 * @param monitor {connect_monitor*} 连接检测对象 - * @return {bool} 是否正常启动了连接检测器,当返回 false 说明当前还有正在 - * 运行的连接检测器,当想再次启动检测器时需要先调用 stop_monitor + * @return {bool} 是否正常启动了连接检测器,当返回 false 说明当前还有 + * 正在运行的连接检测器,当想再次启动检测器时需要先调用 stop_monitor */ bool start_monitor(connect_monitor* monitor); /** * 停止后台检测线程 - * @param graceful {bool} 是否在关闭检测线程时需要等待所有的检测连接关闭后 - * 才返回,当连接池集群对象为进程空间内不会多次分配与释放时,则该值可以设为 false - * 从而使检测线程快速退出,否则应该等待所有检测连接关闭后再使检测线程退出 - * @return {connect_monitor*} 返回 start_monitor 设置的检测器,同时内部 - * 的 monitor_ 成员自动置 NULL + * @param graceful {bool} 是否在关闭检测线程时需要等待所有的检测连接 + * 关闭后才返回,当连接池集群对象为进程空间内不会多次分配与释放时, + * 则该值可以设为 false 从而使检测线程快速退出,否则应该等待所有检测 + * 连接关闭后再使检测线程退出 + * @return {connect_monitor*} 返回 start_monitor 设置的检测器,同时 + * 内部的 monitor_ 成员自动置 NULL */ connect_monitor* stop_monitor(bool graceful = true); @@ -181,7 +184,7 @@ class ACL_CPP_API connect_manager /** * 纯虚函数,子类必须实现此函数用来创建连接池对象 * @param addr {const char*} 服务器监听地址,格式:ip:port - * @param count {size_t} 连接池的大小限制,当该值为 0 时,则连接池没有限制 + * @param count {size_t} 连接池的大小限制,为 0 时,则连接池没有限制 * @param idx {size_t} 该连接池对象在集合中的下标位置(从 0 开始) * @return {connect_pool*} 返回创建的连接池对象 */ diff --git a/lib_acl_cpp/include/acl_cpp/db/db_mysql.hpp b/lib_acl_cpp/include/acl_cpp/db/db_mysql.hpp index 256249fe1..5b6868baf 100644 --- a/lib_acl_cpp/include/acl_cpp/db/db_mysql.hpp +++ b/lib_acl_cpp/include/acl_cpp/db/db_mysql.hpp @@ -60,6 +60,14 @@ class ACL_CPP_API db_mysql : public db_handle return conn_; } + /** + * 当动态加载 libmysqlclient.so / libmysqlclient.dll 时,可以调用本 + * 静态函数显式动态加载 mysql 客户端库,如果加载失败,内部会自动产生 + * 断言,以免运行时出错,也可不调用本函数,使 db_mysql 类对象内部在 + * 使用时隐式加载 mysql 动态库 + */ + static void load(void); + /********************************************************************/ /* 以下为基类 db_handle 的虚接口 */ /********************************************************************/ diff --git a/lib_acl_cpp/src/db/db_mysql.cpp b/lib_acl_cpp/src/db/db_mysql.cpp index 269d4912a..6cd691577 100644 --- a/lib_acl_cpp/src/db/db_mysql.cpp +++ b/lib_acl_cpp/src/db/db_mysql.cpp @@ -391,6 +391,15 @@ void db_mysql::sane_mysql_init(const char* dbaddr, const char* dbname, conn_ = NULL; } +void db_mysql::load(void) +{ +#ifdef HAS_MYSQL_DLL + acl_pthread_once(&__mysql_once, __mysql_dll_load); +#else + logger_warn("link mysql library in static way!"); +#endif +} + db_mysql::db_mysql(const char* dbaddr, const char* dbname, const char* dbuser, const char* dbpass, unsigned long dbflags /* = 0 */, bool auto_commit /* = true */, @@ -832,6 +841,11 @@ bool db_mysql::rollback() namespace acl { +void db_mysql::load(void) +{ + logger_fatal("Please #define HAS_MYSQL_DLL first"); +} + void db_mysql::sane_mysql_init(const char*, const char*, const char*, const char*, unsigned long, bool, int, int, const char*) diff --git a/lib_acl_cpp/src/serialize/gsoner.cpp b/lib_acl_cpp/src/serialize/gsoner.cpp index 2319852c2..296974b0c 100644 --- a/lib_acl_cpp/src/serialize/gsoner.cpp +++ b/lib_acl_cpp/src/serialize/gsoner.cpp @@ -1208,6 +1208,8 @@ bool gsoner::check_member() first == "signed" || first == "int" || first == "long" || + first == "size_t" || + first == "ssize_t" || first == "short" || first == "int16_t"|| first == "uint16_t" || diff --git a/lib_fiber/c/src/event_epoll.c b/lib_fiber/c/src/event_epoll.c index 98963d12b..834d4436b 100644 --- a/lib_fiber/c/src/event_epoll.c +++ b/lib_fiber/c/src/event_epoll.c @@ -16,10 +16,15 @@ static epoll_ctl_fn __sys_epoll_ctl = NULL; void hook_epoll(void) { + static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; - if (__called) + (void) acl_pthread_mutex_lock(&__lock); + + if (__called) { + (void) acl_pthread_mutex_unlock(&__lock); return; + } __called++; @@ -31,6 +36,8 @@ void hook_epoll(void) __sys_epoll_ctl = (epoll_ctl_fn) dlsym(RTLD_NEXT, "epoll_ctl"); acl_assert(__sys_epoll_ctl); + + (void) acl_pthread_mutex_unlock(&__lock); } typedef struct EVENT_EPOLL { diff --git a/lib_fiber/c/src/fiber.c b/lib_fiber/c/src/fiber.c index 64a0bbe9f..c90c43dba 100644 --- a/lib_fiber/c/src/fiber.c +++ b/lib_fiber/c/src/fiber.c @@ -669,10 +669,15 @@ int acl_fiber_status(const ACL_FIBER *fiber) static void fiber_init(void) { + static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; - if (__called != 0) + (void) acl_pthread_mutex_lock(&__lock); + + if (__called != 0) { + (void) pthread_mutex_unlock(&__lock); return; + } __called++; @@ -683,6 +688,8 @@ static void fiber_init(void) #endif __sys_fcntl = (fcntl_fn) dlsym(RTLD_NEXT, "fcntl"); + (void) acl_pthread_mutex_unlock(&__lock); + hook_io(); hook_net(); hook_epoll(); diff --git a/lib_fiber/c/src/hook_io.c b/lib_fiber/c/src/hook_io.c index 5b07b604a..a63e18552 100644 --- a/lib_fiber/c/src/hook_io.c +++ b/lib_fiber/c/src/hook_io.c @@ -55,10 +55,15 @@ static sendmsg_fn __sys_sendmsg = NULL; void hook_io(void) { + static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; - if (__called) + (void) acl_pthread_mutex_lock(&__lock); + + if (__called) { + (void) acl_pthread_mutex_unlock(&__lock); return; + } __called++; @@ -111,6 +116,8 @@ void hook_io(void) __sys_sendmsg = (sendmsg_fn) dlsym(RTLD_NEXT, "sendmsg"); acl_assert(__sys_sendmsg); + + (void) acl_pthread_mutex_unlock(&__lock); } unsigned int sleep(unsigned int seconds) diff --git a/lib_fiber/c/src/hook_net.c b/lib_fiber/c/src/hook_net.c index 54104e249..aec39ec22 100644 --- a/lib_fiber/c/src/hook_net.c +++ b/lib_fiber/c/src/hook_net.c @@ -52,10 +52,15 @@ static epoll_ctl_fn __sys_epoll_ctl = NULL; void hook_net(void) { + static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; static int __called = 0; - if (__called) + (void) acl_pthread_mutex_lock(&__lock); + + if (__called) { + (void) acl_pthread_mutex_unlock(&__lock); return; + } __called++; @@ -107,6 +112,8 @@ void hook_net(void) __sys_epoll_ctl = (epoll_ctl_fn) dlsym(RTLD_NEXT, "epoll_ctl"); acl_assert(__sys_epoll_ctl); + + (void) acl_pthread_mutex_unlock(&__lock); } int socket(int domain, int type, int protocol) @@ -992,14 +999,13 @@ void acl_fiber_set_dns(const char* ip, int port) #define SKIP_WHILE(cond, cp) { while (*cp && (cond)) cp++; } -static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; - static void get_dns(char *ip, size_t size) { const char *filepath = "/etc/resolv.conf"; ACL_VSTREAM *fp; char buf[4096], *ptr; ACL_ARGV *tokens; + static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER; (void) acl_pthread_mutex_lock(&__lock);