aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-09-19 13:38:49 +0200
committerOvahlord <dreadkiller@gmx.de>2024-09-21 05:50:20 +0200
commit3cde0837450ee8cef4df4553cb0e1753b8b5a077 (patch)
treed0554c41f6acbdcda8bb03e6e97d05467025a0cb
parent249d1372bb5e1f0729324d7b0e4629eb05db388b (diff)
Core/Database: Change database async thread shutdown to fix some corner cases leading to servers being stuck on shutdown (for example with exit() call)
(cherry picked from commit 11a832fa8ba2362a0efcde601e7225582326e0da)
-rw-r--r--src/server/database/Database/MySQLConnection.cpp19
-rw-r--r--src/server/database/Database/MySQLConnection.h3
2 files changed, 15 insertions, 7 deletions
diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp
index 7efe93c34f7..3437fc55b1d 100644
--- a/src/server/database/Database/MySQLConnection.cpp
+++ b/src/server/database/Database/MySQLConnection.cpp
@@ -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 {};
}
diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h
index db8ff40a2ab..2b9a96e6a28 100644
--- a/src/server/database/Database/MySQLConnection.h
+++ b/src/server/database/Database/MySQLConnection.h
@@ -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)