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
{
public:
connection_ptr(IdConnection<Connection> *c, connection_pool<Connection> &pool)
connection_ptr(IdConnection<Connection> *c, connection_pool<Connection> *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<Connection>;
IdConnection<Connection> *connection_;
connection_pool<Connection> &pool_;
IdConnection<Connection> *connection_{};
connection_pool<Connection> *pool_{};
};
template < class Connection >
@ -74,10 +75,10 @@ public:
}
}
connection_ptr<Connection> acquire() {
connection_pointer acquire() {
std::unique_lock<std::mutex> 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<Connection> 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<Connection> *c) {
@ -153,7 +154,7 @@ private:
template<class Connection>
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.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);
}