From 269a72bd93f8565c3c75d9502406c1e18f75d088 Mon Sep 17 00:00:00 2001 From: Frank Park Date: Sat, 25 Mar 2017 07:14:36 -0400 Subject: [PATCH] change container to stack of unique_ptr --- include/sqlpp11/connection_pool.h | 119 +++++++++--------------------- 1 file changed, 36 insertions(+), 83 deletions(-) diff --git a/include/sqlpp11/connection_pool.h b/include/sqlpp11/connection_pool.h index fb7f86c1..6811a9d7 100644 --- a/include/sqlpp11/connection_pool.h +++ b/include/sqlpp11/connection_pool.h @@ -1,6 +1,7 @@ #pragma once #include -#include +#include +#include namespace sqlpp { @@ -10,74 +11,8 @@ namespace sqlpp private: std::mutex connection_pool_mutex; const std::shared_ptr config; - - struct async_connection : Connection - { - async_connection(std::shared_ptr config) - : Connection(config) - {} - bool is_free = true; - }; - - std::vector connections; - unsigned int default_pool_size = 0; - unsigned int current_pool_size = 0; - unsigned int max_pool_size = 0; - - void resize(unsigned int target_pool_size) - { - int lock = try_lock(connection_pool_mutex); - if (lock == -1) - { - throw sqlpp::exception("Connection_pool resize should not be called before locking."); - connection_pool_mutex.unlock(); - } - else - { - int diff = current_pool_size - target_pool_size; - if (!diff) - { - return; - } - - // does not guarantee to resize to target_pool_size - if (diff > 0) - { - for (auto it = connections.begin(); it != connections.end();) - { - if (diff && (*it).is_free) - { - it = connections.erase(it); - diff--; - } - else - { - ++it; - } - } - } - - if (diff < 0) - { - connections.reserve(target_pool_size); - for (int i = 0, count = -diff; i < count; i++) - { - try - { - connections.push_back(async_connection(config)); - diff++; - } - catch (const sqlpp::exception& e) - { - std::cerr << "Failed to spawn new connection." << std::endl; - std::cerr << e.what() << std::endl; - } - } - } - current_pool_size = target_pool_size + diff; - } - } + std::stack> free_connections; public: connection_pool(const std::shared_ptr& config, unsigned int pool_size) @@ -86,11 +21,14 @@ namespace sqlpp std::lock_guard lock(connection_pool_mutex); try { - resize(pool_size); + for (int i = 0; i < pool_size; i++) + { + free_connections.push(std::make_unique(config)); + } } catch (const sqlpp::exception& e) { - std::cerr << "Failed to resize connection pool." << std::endl; + std::cerr << "Failed to spawn new connection." << std::endl; std::cerr << e.what() << std::endl; } } @@ -100,35 +38,50 @@ namespace sqlpp connection_pool& operator=(const connection_pool&) = delete; connection_pool& operator=(connection_pool&&) = delete; - std::shared_ptr get_connection() + std::unique_ptr get_connection() { std::lock_guard lock(connection_pool_mutex); - for (auto& connection : connections) + if (!free_connections.empty()) { - if (connection.is_free) - { - connection.is_free = false; - return std::shared_ptr(static_cast(&connection)); - } + auto connection = std::move(free_connections.top()); + free_connections.pop(); + return connection; } try { - resize(current_pool_size + 1); + auto connection = std::make_unique(config); + return connection; } catch (const sqlpp::exception& e) { - std::cerr << "Failed to resize connection pool." << std::endl; + std::cerr << "Failed to spawn new connection." << std::endl; std::cerr << e.what() << std::endl; + return std::unique_ptr(); } - - return std::shared_ptr(static_cast(&connections.back())); } - void free_connection(const std::shared_ptr& connection) + void free_connection(std::unique_ptr connection) { std::lock_guard lock(connection_pool_mutex); - static_cast(connection.get())->is_free = true; + if (free_connections.size() >= default_pool_size) + { + // Exceeds default size, do nothing and let unique_ptr self destroy. + } + else + { + // TODO: we don't know if the connection is originally from this connection pool. + // There's no way to check because we don't have access to config info in the Connection class: + // connection.get()->_handle->config --- _handle is private + if (connection.get()) + { + free_connections.push(std::move(connection)); + } + else + { + throw sqlpp::exception("Trying to free an empty connection."); + } + } } }; }