From 8ba70cc79ed9cddb4a2f52119535429f214f2675 Mon Sep 17 00:00:00 2001 From: Sascha Kuehl Date: Mon, 27 Nov 2023 20:24:43 +0100 Subject: [PATCH] fixed a bug when acquiring a connection with a specific id --- include/matador/sql/connection_pool.hpp | 29 +++++++++++++------------ test/ConnectionPoolTest.cpp | 13 +++++++++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/matador/sql/connection_pool.hpp b/include/matador/sql/connection_pool.hpp index 0a7091a..0aab972 100644 --- a/include/matador/sql/connection_pool.hpp +++ b/include/matador/sql/connection_pool.hpp @@ -19,7 +19,7 @@ template < class Connection > class connection_ptr { public: - connection_ptr(IdConnection *c, connection_pool &pool) + connection_ptr(IdConnection *c, connection_pool *pool) : connection_(c), pool_(pool) {} ~connection_ptr(); connection_ptr(const connection_ptr &) = delete; @@ -29,15 +29,16 @@ public: , pool_(x.pool_) { x.connection_ = nullptr; + x.pool_ = nullptr; } connection_ptr& operator=(connection_ptr &&x) noexcept { if (this == &x) { return *this; } - connection_ = x.connection_; - pool_ = x.pool_; - x.connection_ = nullptr; + + std::swap(connection_, x.connection_); + std::swap(pool_, x.pool_); return *this; } @@ -52,8 +53,8 @@ public: private: friend class connection_pool; - IdConnection *connection_; - connection_pool &pool_; + IdConnection *connection_{}; + connection_pool *pool_{}; }; template < class Connection > @@ -74,10 +75,10 @@ public: } } - connection_ptr acquire() { + connection_pointer acquire() { std::unique_lock lock(mutex_); if (idle_connections_.empty()) { - return {nullptr, *this}; + return {nullptr, this}; } pointer next_connection{nullptr}; @@ -87,10 +88,10 @@ public: inuse_connections_.insert(std::move(node)); break; } - return {next_connection, *this}; + return {next_connection, this}; } - connection_ptr acquire(size_t id) { + connection_pointer acquire(size_t id) { using namespace std::chrono_literals; pointer next_connection{nullptr}; auto try_count{0}; @@ -98,17 +99,17 @@ public: do { if (auto it = idle_connections_.find(id); it != idle_connections_.end()) { - next_connection = it->second.second; + next_connection = it->second; auto node = idle_connections_.extract(it); inuse_connections_.insert(std::move(node)); } else { lock.unlock(); - std::this_thread::sleep_for(500ms); + std::this_thread::sleep_for(100ms); lock.lock(); } } while(try_count++ < 5); - return {next_connection, *this}; + return {next_connection, this}; } void release(IdConnection *c) { @@ -153,7 +154,7 @@ private: template connection_ptr::~connection_ptr() { - pool_.release(connection_); + pool_->release(connection_); } } diff --git a/test/ConnectionPoolTest.cpp b/test/ConnectionPoolTest.cpp index 88b0f34..62a6ce4 100644 --- a/test/ConnectionPoolTest.cpp +++ b/test/ConnectionPoolTest.cpp @@ -27,15 +27,24 @@ TEST_CASE("Create connection pool", "[connection pool]") { REQUIRE(pool.idle() == 4); REQUIRE(pool.inuse() == 0); + ptr = pool.acquire(3); + REQUIRE(ptr.valid()); + REQUIRE(ptr.id() == 3); + REQUIRE(ptr->is_open()); { auto ptr2 = pool.acquire(); REQUIRE(ptr2.valid()); REQUIRE(ptr2->is_open()); - REQUIRE(pool.idle() == 3); - REQUIRE(pool.inuse() == 1); + REQUIRE(pool.idle() == 2); + REQUIRE(pool.inuse() == 2); } + REQUIRE(pool.idle() == 3); + REQUIRE(pool.inuse() == 1); + + pool.release(ptr); + REQUIRE(!ptr.valid()); REQUIRE(pool.idle() == 4); REQUIRE(pool.inuse() == 0); }