fixed a bug when acquiring a connection with a specific id

This commit is contained in:
Sascha Kuehl 2023-11-27 20:24:43 +01:00
parent 5326102801
commit 8ba70cc79e
2 changed files with 26 additions and 16 deletions

View File

@ -19,7 +19,7 @@ template < class Connection >
class connection_ptr class connection_ptr
{ {
public: public:
connection_ptr(IdConnection<Connection> *c, connection_pool<Connection> &pool) connection_ptr(IdConnection<Connection> *c, connection_pool<Connection> *pool)
: connection_(c), pool_(pool) {} : connection_(c), pool_(pool) {}
~connection_ptr(); ~connection_ptr();
connection_ptr(const connection_ptr &) = delete; connection_ptr(const connection_ptr &) = delete;
@ -29,15 +29,16 @@ public:
, pool_(x.pool_) , pool_(x.pool_)
{ {
x.connection_ = nullptr; x.connection_ = nullptr;
x.pool_ = nullptr;
} }
connection_ptr& operator=(connection_ptr &&x) noexcept connection_ptr& operator=(connection_ptr &&x) noexcept
{ {
if (this == &x) { if (this == &x) {
return *this; return *this;
} }
connection_ = x.connection_;
pool_ = x.pool_; std::swap(connection_, x.connection_);
x.connection_ = nullptr; std::swap(pool_, x.pool_);
return *this; return *this;
} }
@ -52,8 +53,8 @@ public:
private: private:
friend class connection_pool<Connection>; friend class connection_pool<Connection>;
IdConnection<Connection> *connection_; IdConnection<Connection> *connection_{};
connection_pool<Connection> &pool_; connection_pool<Connection> *pool_{};
}; };
template < class Connection > template < class Connection >
@ -74,10 +75,10 @@ public:
} }
} }
connection_ptr<Connection> acquire() { connection_pointer acquire() {
std::unique_lock<std::mutex> lock(mutex_); std::unique_lock<std::mutex> lock(mutex_);
if (idle_connections_.empty()) { if (idle_connections_.empty()) {
return {nullptr, *this}; return {nullptr, this};
} }
pointer next_connection{nullptr}; pointer next_connection{nullptr};
@ -87,10 +88,10 @@ public:
inuse_connections_.insert(std::move(node)); inuse_connections_.insert(std::move(node));
break; break;
} }
return {next_connection, *this}; return {next_connection, this};
} }
connection_ptr<Connection> acquire(size_t id) { connection_pointer acquire(size_t id) {
using namespace std::chrono_literals; using namespace std::chrono_literals;
pointer next_connection{nullptr}; pointer next_connection{nullptr};
auto try_count{0}; auto try_count{0};
@ -98,17 +99,17 @@ public:
do { do {
if (auto it = idle_connections_.find(id); it != idle_connections_.end()) { 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); auto node = idle_connections_.extract(it);
inuse_connections_.insert(std::move(node)); inuse_connections_.insert(std::move(node));
} else { } else {
lock.unlock(); lock.unlock();
std::this_thread::sleep_for(500ms); std::this_thread::sleep_for(100ms);
lock.lock(); lock.lock();
} }
} while(try_count++ < 5); } while(try_count++ < 5);
return {next_connection, *this}; return {next_connection, this};
} }
void release(IdConnection<Connection> *c) { void release(IdConnection<Connection> *c) {
@ -153,7 +154,7 @@ private:
template<class Connection> template<class Connection>
connection_ptr<Connection>::~connection_ptr() { connection_ptr<Connection>::~connection_ptr() {
pool_.release(connection_); pool_->release(connection_);
} }
} }

View File

@ -27,15 +27,24 @@ TEST_CASE("Create connection pool", "[connection pool]") {
REQUIRE(pool.idle() == 4); REQUIRE(pool.idle() == 4);
REQUIRE(pool.inuse() == 0); REQUIRE(pool.inuse() == 0);
ptr = pool.acquire(3);
REQUIRE(ptr.valid());
REQUIRE(ptr.id() == 3);
REQUIRE(ptr->is_open());
{ {
auto ptr2 = pool.acquire(); auto ptr2 = pool.acquire();
REQUIRE(ptr2.valid()); REQUIRE(ptr2.valid());
REQUIRE(ptr2->is_open()); REQUIRE(ptr2->is_open());
REQUIRE(pool.idle() == 3); REQUIRE(pool.idle() == 2);
REQUIRE(pool.inuse() == 1); REQUIRE(pool.inuse() == 2);
} }
REQUIRE(pool.idle() == 3);
REQUIRE(pool.inuse() == 1);
pool.release(ptr);
REQUIRE(!ptr.valid());
REQUIRE(pool.idle() == 4); REQUIRE(pool.idle() == 4);
REQUIRE(pool.inuse() == 0); REQUIRE(pool.inuse() == 0);
} }