mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-03 05:52:27 +00:00
Switch database mutex to recursive because we copy it everywhere
... and I have no idea if any of the calls are re-entrant. yay.
This commit is contained in:
parent
7aa669d041
commit
d1d5c5dd7a
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
: mysql(mysql_init(nullptr))
|
: mysql(mysql_init(nullptr))
|
||||||
, m_mutex(std::make_shared<std::mutex>())
|
, m_mutex(std::make_shared<Mutex>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,12 +220,12 @@ bool DBcore::Open(
|
|||||||
|
|
||||||
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||||
{
|
{
|
||||||
|
// Expects m_mutex to already be locked.
|
||||||
|
|
||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::scoped_lock lock(*m_mutex);
|
|
||||||
|
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@ std::string DBcore::Escape(const std::string& s)
|
|||||||
return temp.data();
|
return temp.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetMutex(const std::shared_ptr<std::mutex>& mutex)
|
void DBcore::SetMutex(const std::shared_ptr<Mutex>& mutex)
|
||||||
{
|
{
|
||||||
DBcore::m_mutex = mutex;
|
DBcore::m_mutex = mutex;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,8 @@ public:
|
|||||||
Closed, Connected, Error
|
Closed, Connected, Error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Mutex = std::recursive_mutex;
|
||||||
|
|
||||||
DBcore();
|
DBcore();
|
||||||
~DBcore();
|
~DBcore();
|
||||||
eStatus GetStatus() { return pStatus; }
|
eStatus GetStatus() { return pStatus; }
|
||||||
@ -59,7 +61,7 @@ public:
|
|||||||
mysql = o.mysql;
|
mysql = o.mysql;
|
||||||
mysqlOwner = false;
|
mysqlOwner = false;
|
||||||
}
|
}
|
||||||
void SetMutex(const std::shared_ptr<std::mutex>& mutex);
|
void SetMutex(const std::shared_ptr<Mutex>& mutex);
|
||||||
|
|
||||||
// only safe on connections shared with other threads if results buffered
|
// only safe on connections shared with other threads if results buffered
|
||||||
// unsafe to use off main thread due to internal server logging
|
// unsafe to use off main thread due to internal server logging
|
||||||
@ -86,8 +88,7 @@ private:
|
|||||||
bool mysqlOwner = true;
|
bool mysqlOwner = true;
|
||||||
eStatus pStatus = Closed;
|
eStatus pStatus = Closed;
|
||||||
|
|
||||||
std::shared_ptr<std::mutex> m_mutex;
|
std::shared_ptr<Mutex> m_mutex;
|
||||||
std::mutex m_query_lock;
|
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
|
|||||||
@ -95,7 +95,7 @@ void TaskScheduler::ProcessWork()
|
|||||||
m_data->cv.wait(lock,
|
m_data->cv.wait(lock,
|
||||||
[this]
|
[this]
|
||||||
{
|
{
|
||||||
return !m_data->running || m_data->tasks.empty();
|
return !m_data->running || !m_data->tasks.empty();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_data->running)
|
if (!m_data->running)
|
||||||
|
|||||||
@ -35,7 +35,7 @@ void PreparedStmt::StmtDeleter::operator()(MYSQL_STMT* stmt) noexcept
|
|||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, std::mutex& mutex, StmtOptions opts)
|
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, DBcore::Mutex& mutex, StmtOptions opts)
|
||||||
: m_stmt(mysql_stmt_init(&mysql), { mutex })
|
: m_stmt(mysql_stmt_init(&mysql), { mutex })
|
||||||
, m_query(std::move(query))
|
, m_query(std::move(query))
|
||||||
, m_options(opts)
|
, m_options(opts)
|
||||||
|
|||||||
@ -17,8 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/dbcore.h"
|
||||||
|
|
||||||
#include "mysql.h"
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -185,7 +185,7 @@ public:
|
|||||||
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
||||||
|
|
||||||
PreparedStmt() = delete;
|
PreparedStmt() = delete;
|
||||||
PreparedStmt(MYSQL& mysql, std::string query, std::mutex& mutex, StmtOptions opts = {});
|
PreparedStmt(MYSQL& mysql, std::string query, DBcore::Mutex& mutex, StmtOptions opts = {});
|
||||||
|
|
||||||
const std::string& GetQuery() const { return m_query; }
|
const std::string& GetQuery() const { return m_query; }
|
||||||
StmtOptions GetOptions() const { return m_options; }
|
StmtOptions GetOptions() const { return m_options; }
|
||||||
@ -221,7 +221,7 @@ private:
|
|||||||
|
|
||||||
struct StmtDeleter
|
struct StmtDeleter
|
||||||
{
|
{
|
||||||
std::mutex& mutex;
|
DBcore::Mutex& mutex;
|
||||||
|
|
||||||
void operator()(MYSQL_STMT* stmt) noexcept;
|
void operator()(MYSQL_STMT* stmt) noexcept;
|
||||||
};
|
};
|
||||||
@ -235,7 +235,7 @@ private:
|
|||||||
std::string m_query;
|
std::string m_query;
|
||||||
StmtOptions m_options = {};
|
StmtOptions m_options = {};
|
||||||
bool m_need_bind = true;
|
bool m_need_bind = true;
|
||||||
std::mutex& m_mutex; // connection mutex
|
DBcore::Mutex& m_mutex; // connection mutex
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mysql
|
} // namespace mysql
|
||||||
|
|||||||
@ -76,7 +76,7 @@ void WorldserverCLI::TestDatabaseConcurrency(int argc, char **argv, argh::parser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
|
|
||||||
db.SetMutex(sharedMutex);
|
db.SetMutex(sharedMutex);
|
||||||
|
|
||||||
|
|||||||
@ -180,7 +180,7 @@ bool WorldBoot::LoadDatabaseConnections()
|
|||||||
// when database and content_db share the same underlying mysql connection
|
// when database and content_db share the same underlying mysql connection
|
||||||
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
||||||
// when database actions are occurring in different threads
|
// when database actions are occurring in different threads
|
||||||
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
database.SetMutex(sharedMutex);
|
database.SetMutex(sharedMutex);
|
||||||
content_db.SetMutex(sharedMutex);
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -246,7 +246,7 @@ int main(int argc, char **argv)
|
|||||||
// when database and content_db share the same underlying mysql connection
|
// when database and content_db share the same underlying mysql connection
|
||||||
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
||||||
// when database actions are occurring in different threads
|
// when database actions are occurring in different threads
|
||||||
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
database.SetMutex(sharedMutex);
|
database.SetMutex(sharedMutex);
|
||||||
content_db.SetMutex(sharedMutex);
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user