fixed a bug when acquiring a connection with a specific id
This commit is contained in:
parent
5326102801
commit
8ba70cc79e
|
|
@ -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_);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue