diff --git a/lib_acl_cpp/include/acl_cpp/connpool/connect_monitor.hpp b/lib_acl_cpp/include/acl_cpp/connpool/connect_monitor.hpp index b6ad6f42d..89ff27178 100644 --- a/lib_acl_cpp/include/acl_cpp/connpool/connect_monitor.hpp +++ b/lib_acl_cpp/include/acl_cpp/connpool/connect_monitor.hpp @@ -63,7 +63,6 @@ public: * @param on {bool} 是否自动关闭过期的空闲连接 * @param kick_dead {bool} 是否检查所有连接的存活状态并关闭异常连接,当该参数 * 为 true 时,connect_client 的子类必须重载 alive() 虚方法,返回连接是否存活 - * @param conns_min {size_t} > 0 表示尽量维持每个连接池中的最小活跃连接数 * @param step {bool} 每次检测连接池个数 * @return {connect_monitor&} */ diff --git a/lib_acl_cpp/include/acl_cpp/connpool/connect_pool.hpp b/lib_acl_cpp/include/acl_cpp/connpool/connect_pool.hpp index 3a904dc9f..73972fc2b 100644 --- a/lib_acl_cpp/include/acl_cpp/connpool/connect_pool.hpp +++ b/lib_acl_cpp/include/acl_cpp/connpool/connect_pool.hpp @@ -101,19 +101,41 @@ public: void put(connect_client* conn, bool keep = true); /** - * 检查连接池中空闲的连接,将过期的连接释放掉 - * @param kick_dead {bool} 是否自动检测死连接并关闭之 + * 检查连接池中空闲的连接,释放过期连接(过期时间使用 set_idle_ttl() 设置的值) * @param exclusive {bool} 内部是否需要加锁 - * @return {size_t} 被释放的空闲连接个数 + * @param kick_dead {bool} 是否自动检测死连接并关闭之 + * @return {size_t} 返回被释放空闲连接个数 */ - size_t check_idle(bool kick_dead, bool exclusive); + size_t check_idle(bool kick_dead, bool exclusive = true); /** - * 检测连接状态,并关闭断开连接 + * 检查连接池中空闲的连接,释放过期连接 + * @param ttl {time_t} 该值 >= 0 时,过期时间大于此值的连接将被关闭 * @param exclusive {bool} 内部是否需要加锁 + * @param kick_dead {bool} 是否自动检测死连接并关闭之 + * @return {size_t} 返回被释放空闲连接个数 + */ + size_t check_idle(time_t ttl, bool kick_dead, bool exclusive = true); + + /** + * 检查连接池中空闲的连接,释放过期连接 + * @param ttl {time_t} 该值 >= 0 时,过期时间大于此值的连接将被关闭 + * @param exclusive {bool} 内部是否需要加锁 + * @return {size_t} 返回被释放空闲连接个数 + */ + size_t check_idle(time_t ttl, bool exclusive = true); + + /** + * 检测连接状态,并关闭断开连接,内部自动加锁保护 + * @param count {size_t} 检测的连接个数,缺省值为 0 表示检测所有连接 * @return {size_t} 被关闭的连接个数 */ - size_t check_dead(bool exclusive = true); + size_t check_dead(size_t count = 0); + + /** + * 尽量保持由 set_conns_min() 设置的最小连接数 + */ + void keep_conns(); /** * 设置连接池的存活状态 @@ -232,13 +254,7 @@ protected: std::list pool_; // 连接池集合 size_t kick_idle_conns(time_t ttl); // 关闭过期的连接 - - /** - * 保持最小活跃连接数 - * @param min {size_t} 该值 > 0 表示希望连接池中最小的活跃连接数 - * @return {size_t} 返回实际的连接数 - */ - size_t keep_conns(size_t min); + connect_client* peek_back(); // 从尾部 Peek 连接 }; class ACL_CPP_API connect_guard : public noncopyable { diff --git a/lib_acl_cpp/src/connpool/connect_pool.cpp b/lib_acl_cpp/src/connpool/connect_pool.cpp index cc869d7bc..39e2c4094 100644 --- a/lib_acl_cpp/src/connpool/connect_pool.cpp +++ b/lib_acl_cpp/src/connpool/connect_pool.cpp @@ -324,13 +324,23 @@ void connect_pool::set_alive(bool yes /* true | false */) lock_.unlock(); } -size_t connect_pool::check_idle(bool kick_dead, bool exclusive) +size_t connect_pool::check_idle(time_t ttl, bool exclusive /* true */) +{ + return check_idle(ttl, false, exclusive); +} + +size_t connect_pool::check_idle(bool kick_dead, bool exclusive /* true */) +{ + return check_idle(idle_ttl_, kick_dead, exclusive); +} + +size_t connect_pool::check_idle(time_t ttl, bool kick_dead, bool exclusive) { if (exclusive) { lock_.lock(); } - if (pool_.empty()) { + if (pool_.empty() && min_ == 0) { if (exclusive) { lock_.unlock(); } @@ -339,7 +349,7 @@ size_t connect_pool::check_idle(bool kick_dead, bool exclusive) size_t n = 0; - if (idle_ttl_ == 0) { + if (ttl == 0) { std::list::iterator it = pool_.begin(); for (; it != pool_.end(); ++it) { delete *it; @@ -355,22 +365,24 @@ size_t connect_pool::check_idle(bool kick_dead, bool exclusive) return n; } - if (idle_ttl_ > 0) { - n += kick_idle_conns(idle_ttl_); + if (ttl > 0) { + n += kick_idle_conns(ttl); } - if (kick_dead) { - n += check_dead(false); - } - - if (min_ > 0) { - keep_conns(min_); - } + size_t count = count_; if (exclusive) { lock_.unlock(); } + if (kick_dead) { + n += check_dead(count); + } + + if (min_ > 0) { + keep_conns(); + } + return n; } @@ -414,62 +426,85 @@ size_t connect_pool::kick_idle_conns(time_t ttl) return n; } -size_t connect_pool::check_dead(bool exclusive /* true */) +size_t connect_pool::check_dead(size_t count /* 0 */) { - if (exclusive) { + if (count == 0) { lock_.lock(); + count = count_; + lock_.unlock(); } size_t n = 0; - std::list::iterator it; + for (size_t i = 0; i < count; i++) { + connect_client* conn = peek_back(); + if (conn == NULL) { + break; + } - // Check all the dead connections and close them. - for (it = pool_.begin(); it != pool_.end();) { - if ((*it)->alive()) { - ++it; + if (conn->alive()) { + put(conn); continue; } - if ((*it)->get_pool() == this) { - count_--; + if (conn->get_pool() == this) { + lock_.lock(); + --count_; + lock_.unlock(); } - - delete *it; - it = pool_.erase(it); + delete conn; n++; } - if (exclusive) { - lock_.unlock(); - } return n; } -size_t connect_pool::keep_conns(size_t min) +connect_client* connect_pool::peek_back() { - if (min > 0 && min > count_) { - min -= count_; + lock_.lock(); + std::list::reverse_iterator rit = pool_.rbegin(); + if (rit == pool_.rend()) { + lock_.unlock(); + return NULL; + } + + std::list::iterator it = --rit.base(); + connect_client* conn = *it; + pool_.erase(it); + lock_.unlock(); + return conn; +} + +void connect_pool::keep_conns() +{ + lock_.lock(); + size_t min; + if (min_ > 0 && min_ > count_) { + min = min_ - count_; } else { min = 0; } + lock_.unlock(); for (size_t i = 0; i < min; i++) { connect_client* conn = create_connect(); if (conn == NULL) { + logger_error("Create connection error"); break; } + if (!conn->open()) { - logger_error("Open connection error, conn=%p", conn); + logger_error("Open error: %s", last_serror()); delete conn; break; } + lock_.lock(); count_++; + lock_.unlock(); conn->set_pool(this); put(conn, true); } - return count_; } } // namespace acl diff --git a/lib_acl_cpp/src/connpool/tcp_ipc.cpp b/lib_acl_cpp/src/connpool/tcp_ipc.cpp index cbfa279ac..6750772f2 100644 --- a/lib_acl_cpp/src/connpool/tcp_ipc.cpp +++ b/lib_acl_cpp/src/connpool/tcp_ipc.cpp @@ -10,7 +10,7 @@ namespace acl { -tcp_ipc::tcp_ipc(void) +tcp_ipc::tcp_ipc() : max_(0) , ttl_(60) , conn_timeout_(10) diff --git a/unit_test/net/test_net.c b/unit_test/net/test_net.c index ddc909adf..7ae8dd78c 100644 --- a/unit_test/net/test_net.c +++ b/unit_test/net/test_net.c @@ -8,7 +8,7 @@ #include "test_net.h" #include "test_nettab.h" -void test_net_register() +void test_net_register(void) { aut_register(__test_fn_tab); } diff --git a/unit_test/stdlib/test_avl.c b/unit_test/stdlib/test_avl.c index c71a474a6..0e9686f1e 100644 --- a/unit_test/stdlib/test_avl.c +++ b/unit_test/stdlib/test_avl.c @@ -53,7 +53,7 @@ int test_avl_create(AUT_LINE *test_line acl_unused, void *arg acl_unused) int test_avl_add_bat(AUT_LINE *test_line acl_unused, void *arg acl_unused) { MY_TYPE *pm, m; - int i, n = 0; + int i; for (i = 0; i < 100; i++) { snprintf(m.name, sizeof(m.name), "%d", i); @@ -69,7 +69,6 @@ int test_avl_add_bat(AUT_LINE *test_line acl_unused, void *arg acl_unused) snprintf(pm->value, sizeof(pm->value), "value(%d)", i); acl_avl_add(__avl_tree, pm); printf(">>add one, key(%s), value(%s)\r\n", pm->name, pm->value); - n++; } return (0); diff --git a/unit_test/stdlib/test_stdlib.c b/unit_test/stdlib/test_stdlib.c index 127844aa8..c28061fcf 100644 --- a/unit_test/stdlib/test_stdlib.c +++ b/unit_test/stdlib/test_stdlib.c @@ -9,7 +9,7 @@ #include "test_stdtab.h" -void test_stdlib_register() +void test_stdlib_register(void) { aut_register(__test_fn_tab); } diff --git a/unit_test/unit_test/unit_test.c b/unit_test/unit_test/unit_test.c index 64a477d1e..bbee9dc1e 100644 --- a/unit_test/unit_test/unit_test.c +++ b/unit_test/unit_test/unit_test.c @@ -3,7 +3,7 @@ #include "unit_test.h" #include "unit_test_tab.h" -void test_unit_register() +void test_unit_register(void) { aut_register(__test_fn_tab); }