Core/Database: Change database async thread shutdown to fix some corner cases leading to servers being stuck on shutdown (for example with exit() call)

This commit is contained in:
Shauren
2024-09-19 13:38:49 +02:00
parent 588639fc6c
commit 11a832fa8b
2 changed files with 15 additions and 7 deletions

View File

@@ -47,6 +47,12 @@ MySQLConnectionInfo::MySQLConnectionInfo(std::string const& infoString)
ssl.assign(tokens[5]);
}
struct MySQLConnection::WorkerThread
{
std::thread ThreadHandle;
boost::asio::executor_work_guard<Trinity::Asio::IoContext::Executor> WorkGuard;
};
MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo, ConnectionFlags connectionFlags) :
m_reconnecting(false),
m_prepareError(false),
@@ -66,7 +72,8 @@ void MySQLConnection::Close()
// Stop the worker thread before the statements are cleared
if (m_workerThread)
{
m_workerThread->join();
m_workerThread->WorkGuard.reset();
m_workerThread->ThreadHandle.join();
m_workerThread.reset();
}
@@ -444,18 +451,18 @@ uint32 MySQLConnection::GetLastError()
void MySQLConnection::StartWorkerThread(Trinity::Asio::IoContext* context)
{
m_workerThread = std::make_unique<std::thread>([context]
{
boost::asio::executor_work_guard executorWorkGuard = boost::asio::make_work_guard(context->get_executor());
boost::asio::executor_work_guard executorWorkGuard = boost::asio::make_work_guard(context->get_executor()); // construct guard before thread starts running
context->run();
m_workerThread = std::make_unique<WorkerThread>(WorkerThread{
.ThreadHandle = std::thread([context] { context->run(); }),
.WorkGuard = std::move(executorWorkGuard)
});
}
std::thread::id MySQLConnection::GetWorkerThreadId() const
{
if (m_workerThread)
return m_workerThread->get_id();
return m_workerThread->ThreadHandle.get_id();
return {};
}

View File

@@ -104,7 +104,8 @@ class TC_DATABASE_API MySQLConnection
private:
bool _HandleMySQLErrno(uint32 errNo, uint8 attempts = 5);
std::unique_ptr<std::thread> m_workerThread; //!< Core worker thread.
struct WorkerThread;
std::unique_ptr<WorkerThread> m_workerThread; //!< Core worker thread.
MySQLHandle* m_Mysql; //!< MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //!< Connection info (used for logging)
ConnectionFlags m_connectionFlags; //!< Connection flags (for preparing relevant statements)