更新 src/redis.cpp
This commit is contained in:
@@ -45,22 +45,34 @@ void module::redis_pool::close()
|
||||
|
||||
std::shared_ptr<module::redis> module::redis_pool::get()
|
||||
{
|
||||
if (m_closed)
|
||||
{
|
||||
throw ylib::exception("connection pool is closed");
|
||||
}
|
||||
redisContext* ctx = nullptr;
|
||||
if (m_queue.pop(ctx))
|
||||
{
|
||||
std::unique_lock<std::mutex> uni(m_mutex);
|
||||
if (m_closed)
|
||||
{
|
||||
throw ylib::exception("connection pool is closed");
|
||||
}
|
||||
if (m_queue.pop(ctx))
|
||||
{
|
||||
m_pop_size++;
|
||||
return std::make_shared<module::redis>(ctx, this);
|
||||
}
|
||||
if (m_pop_size >= m_max_size)
|
||||
throw ylib::exception("connection pool releases more connections than the maximum number");
|
||||
// Reserve a slot before unlocking for the blocking connect.
|
||||
m_pop_size++;
|
||||
return std::make_shared<module::redis>(ctx, this);
|
||||
}
|
||||
if (m_pop_size >= m_max_size)
|
||||
throw ylib::exception("connection pool releases more connections than the maximum number");
|
||||
|
||||
ctx = reget(nullptr);
|
||||
|
||||
m_pop_size++;
|
||||
try
|
||||
{
|
||||
ctx = reget(nullptr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::unique_lock<std::mutex> uni(m_mutex);
|
||||
m_pop_size--;
|
||||
throw;
|
||||
}
|
||||
return std::make_shared<module::redis>(ctx, this);
|
||||
}
|
||||
|
||||
@@ -170,13 +182,15 @@ void module::redis_pool::recover(redisContext* ctx)
|
||||
{
|
||||
if (ctx == nullptr)
|
||||
return;
|
||||
std::unique_lock<std::mutex> uni(m_mutex);
|
||||
if (m_closed)
|
||||
{
|
||||
redisFree(ctx);
|
||||
return;
|
||||
}
|
||||
m_queue.push(ctx);
|
||||
m_pop_size--;
|
||||
if (m_pop_size > 0)
|
||||
m_pop_size--;
|
||||
}
|
||||
|
||||
module::redis::redis(redisContext* context, redis_pool* pool):m_context(context),m_pool(pool)
|
||||
@@ -190,7 +204,14 @@ module::redis::~redis()
|
||||
}
|
||||
void module::redis::close()
|
||||
{
|
||||
m_pool->recover(m_context);
|
||||
// Guard against double-return: Lua close() + shared_ptr destructor
|
||||
// previously pushed the same redisContext* into the pool twice, which
|
||||
// leads to concurrent redisCommand use and "double free or corruption".
|
||||
if (m_context == nullptr || m_pool == nullptr)
|
||||
return;
|
||||
redisContext* ctx = m_context;
|
||||
m_context = nullptr;
|
||||
m_pool->recover(ctx);
|
||||
}
|
||||
sol::object module::redis::command(const std::string& cmd, sol::this_state ts)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user