mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 00:46:46 +00:00
Remove Mutex class, replace with std::mutex
Also removes unused Condition class
This commit is contained in:
@@ -7,7 +7,6 @@ set(common_sources
|
|||||||
classes.cpp
|
classes.cpp
|
||||||
cli/eqemu_command_handler.cpp
|
cli/eqemu_command_handler.cpp
|
||||||
compression.cpp
|
compression.cpp
|
||||||
condition.cpp
|
|
||||||
content/world_content_service.cpp
|
content/world_content_service.cpp
|
||||||
crash.cpp
|
crash.cpp
|
||||||
crc16.cpp
|
crc16.cpp
|
||||||
@@ -61,7 +60,6 @@ set(common_sources
|
|||||||
memory_mapped_file.cpp
|
memory_mapped_file.cpp
|
||||||
misc.cpp
|
misc.cpp
|
||||||
misc_functions.cpp
|
misc_functions.cpp
|
||||||
mutex.cpp
|
|
||||||
mysql_request_result.cpp
|
mysql_request_result.cpp
|
||||||
mysql_request_row.cpp
|
mysql_request_row.cpp
|
||||||
mysql_stmt.cpp
|
mysql_stmt.cpp
|
||||||
@@ -548,7 +546,6 @@ set(common_headers
|
|||||||
cli/terminal_color.hpp
|
cli/terminal_color.hpp
|
||||||
classes.h
|
classes.h
|
||||||
compression.h
|
compression.h
|
||||||
condition.h
|
|
||||||
content/world_content_service.h
|
content/world_content_service.h
|
||||||
crash.h
|
crash.h
|
||||||
crc16.h
|
crc16.h
|
||||||
@@ -627,7 +624,6 @@ set(common_headers
|
|||||||
memory_mapped_file.h
|
memory_mapped_file.h
|
||||||
misc.h
|
misc.h
|
||||||
misc_functions.h
|
misc_functions.h
|
||||||
mutex.h
|
|
||||||
mysql_request_result.h
|
mysql_request_result.h
|
||||||
mysql_request_row.h
|
mysql_request_row.h
|
||||||
mysql_stmt.h
|
mysql_stmt.h
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "condition.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
|
|
||||||
Condition::Condition()
|
|
||||||
{
|
|
||||||
m_events[SignalEvent] = CreateEvent (nullptr, // security
|
|
||||||
FALSE, // is auto-reset event?
|
|
||||||
FALSE, // is signaled initially?
|
|
||||||
nullptr); // name
|
|
||||||
m_events[BroadcastEvent] = CreateEvent (nullptr, // security
|
|
||||||
TRUE, // is auto-reset event?
|
|
||||||
FALSE, // is signaled initially?
|
|
||||||
nullptr); // name
|
|
||||||
m_waiters = 0;
|
|
||||||
InitializeCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Condition::~Condition()
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&CSMutex);
|
|
||||||
CloseHandle(m_events[SignalEvent]);
|
|
||||||
CloseHandle(m_events[BroadcastEvent]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Signal()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
if(m_waiters > 0)
|
|
||||||
SetEvent(m_events[SignalEvent]);
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::SignalAll()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
if(m_waiters > 0)
|
|
||||||
SetEvent(m_events[BroadcastEvent]);
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Wait()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
|
|
||||||
m_waiters++;
|
|
||||||
|
|
||||||
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
int result = WaitForMultipleObjects (_eventCount, m_events, FALSE, INFINITE);
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
|
|
||||||
m_waiters--;
|
|
||||||
|
|
||||||
//see if we are the last person waiting on the condition, and there was a broadcast
|
|
||||||
//if so, we need to reset the broadcast event.
|
|
||||||
if(m_waiters == 0 && result == (WAIT_OBJECT_0+BroadcastEvent))
|
|
||||||
ResetEvent(m_events[BroadcastEvent]);
|
|
||||||
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
Condition::Condition()
|
|
||||||
{
|
|
||||||
pthread_cond_init(&cond,nullptr);
|
|
||||||
pthread_mutex_init(&mutex,nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Signal()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_signal(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::SignalAll()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_broadcast(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Wait()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_wait(&cond,&mutex);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
I commented this specifically because I think it might be very
|
|
||||||
difficult to write a windows counterpart to it, so I would like
|
|
||||||
to discourage its use until we can confirm that it can be reasonably
|
|
||||||
implemented on windows.
|
|
||||||
|
|
||||||
bool Condition::TimedWait(unsigned long usec)
|
|
||||||
{
|
|
||||||
struct timeval now;
|
|
||||||
struct timespec timeout;
|
|
||||||
int retcode=0;
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
gettimeofday(&now,nullptr);
|
|
||||||
now.tv_usec+=usec;
|
|
||||||
timeout.tv_sec = now.tv_sec + (now.tv_usec/1000000);
|
|
||||||
timeout.tv_nsec = (now.tv_usec%1000000) *1000;
|
|
||||||
//cout << "now=" << now.tv_sec << "."<<now.tv_usec << endl;
|
|
||||||
//cout << "timeout=" << timeout.tv_sec << "."<<timeout.tv_nsec << endl;
|
|
||||||
retcode=pthread_cond_timedwait(&cond,&mutex,&timeout);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
|
|
||||||
return retcode!=ETIMEDOUT;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Condition::~Condition()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_destroy(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
pthread_mutex_destroy(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/platform/posix/include_pthreads.h"
|
|
||||||
#include "common/platform/win/include_windows.h"
|
|
||||||
|
|
||||||
//Sombody, someday needs to figure out how to implement a condition
|
|
||||||
//system on windows...
|
|
||||||
|
|
||||||
|
|
||||||
class Condition {
|
|
||||||
private:
|
|
||||||
#ifdef WIN32
|
|
||||||
enum {
|
|
||||||
SignalEvent = 0,
|
|
||||||
BroadcastEvent,
|
|
||||||
_eventCount
|
|
||||||
};
|
|
||||||
|
|
||||||
HANDLE m_events[_eventCount];
|
|
||||||
uint32 m_waiters;
|
|
||||||
CRITICAL_SECTION CSMutex;
|
|
||||||
#else
|
|
||||||
pthread_cond_t cond;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
Condition();
|
|
||||||
void Signal();
|
|
||||||
void SignalAll();
|
|
||||||
void Wait();
|
|
||||||
// bool TimedWait(unsigned long usec);
|
|
||||||
~Condition();
|
|
||||||
};
|
|
||||||
+2
-2
@@ -728,7 +728,7 @@ bool Database::LoadVariables()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockMutex lock(&Mvarcache);
|
std::scoped_lock lock(Mvarcache);
|
||||||
|
|
||||||
for (const auto& e : l) {
|
for (const auto& e : l) {
|
||||||
varcache.last_update = std::time(nullptr);
|
varcache.last_update = std::time(nullptr);
|
||||||
@@ -747,7 +747,7 @@ bool Database::LoadVariables()
|
|||||||
|
|
||||||
bool Database::GetVariable(const std::string& name, std::string& value)
|
bool Database::GetVariable(const std::string& name, std::string& value)
|
||||||
{
|
{
|
||||||
LockMutex lock(&Mvarcache);
|
std::scoped_lock lock(Mvarcache);
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+3
-4
@@ -20,13 +20,12 @@
|
|||||||
#include "common/dbcore.h"
|
#include "common/dbcore.h"
|
||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/eqemu_logsys.h"
|
#include "common/eqemu_logsys.h"
|
||||||
#include "common/linked_list.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#define AUTHENTICATION_TIMEOUT 60
|
#define AUTHENTICATION_TIMEOUT 60
|
||||||
#define INVALID_ID 0xFFFFFFFF
|
#define INVALID_ID 0xFFFFFFFF
|
||||||
@@ -265,7 +264,7 @@ public:
|
|||||||
uint64_t GetNextTableId(const std::string& table_name);
|
uint64_t GetNextTableId(const std::string& table_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex Mvarcache;
|
std::mutex Mvarcache;
|
||||||
VarCache_Struct varcache;
|
VarCache_Struct varcache;
|
||||||
|
|
||||||
/* Groups, utility methods. */
|
/* Groups, utility methods. */
|
||||||
|
|||||||
+23
-40
@@ -33,17 +33,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
|
: mysql(mysql_init(nullptr))
|
||||||
|
, m_mutex(std::make_shared<std::mutex>())
|
||||||
{
|
{
|
||||||
mysql = mysql_init(nullptr);
|
|
||||||
mysqlOwner = true;
|
|
||||||
pHost = nullptr;
|
|
||||||
pUser = nullptr;
|
|
||||||
pPassword = nullptr;
|
|
||||||
pDatabase = nullptr;
|
|
||||||
pCompress = false;
|
|
||||||
pSSL = false;
|
|
||||||
pStatus = Closed;
|
|
||||||
m_mutex = new Mutex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore()
|
||||||
@@ -56,20 +48,17 @@ DBcore::~DBcore()
|
|||||||
if (mysqlOwner) {
|
if (mysqlOwner) {
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(pHost);
|
|
||||||
safe_delete_array(pUser);
|
|
||||||
safe_delete_array(pPassword);
|
|
||||||
safe_delete_array(pDatabase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!m_mutex->trylock()) {
|
if (!m_mutex->try_lock())
|
||||||
|
{
|
||||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_ping(mysql);
|
mysql_ping(mysql);
|
||||||
m_mutex->unlock();
|
m_mutex->unlock();
|
||||||
}
|
}
|
||||||
@@ -92,7 +81,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
@@ -217,15 +206,12 @@ bool DBcore::Open(
|
|||||||
bool iSSL
|
bool iSSL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
safe_delete_array(pHost);
|
|
||||||
safe_delete_array(pUser);
|
m_host = iHost;
|
||||||
safe_delete_array(pPassword);
|
m_user = iUser;
|
||||||
safe_delete_array(pDatabase);
|
m_password = iPassword;
|
||||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
m_database = iDatabase;
|
||||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
|
||||||
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
|
|
||||||
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
|
|
||||||
pCompress = iCompress;
|
pCompress = iCompress;
|
||||||
pPort = iPort;
|
pPort = iPort;
|
||||||
pSSL = iSSL;
|
pSSL = iSSL;
|
||||||
@@ -237,7 +223,9 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
LockMutex lock(m_mutex);
|
|
||||||
|
std::scoped_lock lock(*m_mutex);
|
||||||
|
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -245,7 +233,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql_init(mysql); // Initialize structure again
|
mysql_init(mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (m_host.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -268,11 +256,10 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &off);
|
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &off);
|
||||||
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &off);
|
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &off);
|
||||||
}
|
}
|
||||||
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(mysql, m_host.c_str(), m_user.c_str(), m_password.c_str(), m_database.c_str(), pPort, nullptr, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
|
|
||||||
std::string connected_origin_host = pHost;
|
SetOriginHost(m_host);
|
||||||
SetOriginHost(connected_origin_host);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -293,9 +280,9 @@ const std::string &DBcore::GetOriginHost() const
|
|||||||
return origin_host;
|
return origin_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetOriginHost(const std::string &origin_host)
|
void DBcore::SetOriginHost(const std::string& originHost)
|
||||||
{
|
{
|
||||||
DBcore::origin_host = origin_host;
|
DBcore::origin_host = originHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DBcore::Escape(const std::string& s)
|
std::string DBcore::Escape(const std::string& s)
|
||||||
@@ -307,12 +294,8 @@ std::string DBcore::Escape(const std::string& s)
|
|||||||
return temp.data();
|
return temp.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetMutex(Mutex *mutex)
|
void DBcore::SetMutex(const std::shared_ptr<std::mutex>& mutex)
|
||||||
{
|
{
|
||||||
if (m_mutex && m_mutex != mutex) {
|
|
||||||
safe_delete(m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBcore::m_mutex = mutex;
|
DBcore::m_mutex = mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +309,7 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
@@ -449,5 +432,5 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|||||||
|
|
||||||
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
||||||
{
|
{
|
||||||
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
|
return mysql::PreparedStmt(*mysql, std::move(query), *m_mutex);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/mysql_request_result.h"
|
#include "common/mysql_request_result.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
@@ -29,7 +28,8 @@
|
|||||||
|
|
||||||
namespace mysql { class PreparedStmt; }
|
namespace mysql { class PreparedStmt; }
|
||||||
|
|
||||||
class DBcore {
|
class DBcore
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum eStatus {
|
enum eStatus {
|
||||||
Closed, Connected, Error
|
Closed, Connected, Error
|
||||||
@@ -48,17 +48,17 @@ public:
|
|||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
|
|
||||||
const std::string &GetOriginHost() const;
|
const std::string& GetOriginHost() const;
|
||||||
void SetOriginHost(const std::string &origin_host);
|
void SetOriginHost(const std::string& origin_host);
|
||||||
|
|
||||||
bool DoesTableExist(const std::string& table_name);
|
bool DoesTableExist(const std::string& table_name);
|
||||||
|
|
||||||
void SetMySQL(const DBcore &o)
|
void SetMySQL(const DBcore& o)
|
||||||
{
|
{
|
||||||
mysql = o.mysql;
|
mysql = o.mysql;
|
||||||
mysqlOwner = false;
|
mysqlOwner = false;
|
||||||
}
|
}
|
||||||
void SetMutex(Mutex *mutex);
|
void SetMutex(const std::shared_ptr<std::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
|
||||||
@@ -81,22 +81,22 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||||
|
|
||||||
MYSQL* mysql;
|
MYSQL* mysql = nullptr;
|
||||||
bool mysqlOwner;
|
bool mysqlOwner = true;
|
||||||
Mutex *m_mutex;
|
eStatus pStatus = Closed;
|
||||||
eStatus pStatus;
|
|
||||||
|
|
||||||
std::mutex m_query_lock{};
|
std::shared_ptr<std::mutex> m_mutex;
|
||||||
|
std::mutex m_query_lock;
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
std::string m_host;
|
||||||
char *pUser;
|
std::string m_user;
|
||||||
char *pPassword;
|
std::string m_password;
|
||||||
char *pDatabase;
|
std::string m_database;
|
||||||
bool pCompress;
|
bool pCompress = false;
|
||||||
uint32 pPort;
|
uint32 pPort = 0;
|
||||||
bool pSSL;
|
bool pSSL = false;
|
||||||
|
|
||||||
// allows multiple queries to be executed within the same query
|
// allows multiple queries to be executed within the same query
|
||||||
// do not use this under normal operation
|
// do not use this under normal operation
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "mutex.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#define DEBUG_MUTEX_CLASS 0
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
bool IsTryLockSupported();
|
|
||||||
bool TrylockSupported = IsTryLockSupported();
|
|
||||||
|
|
||||||
bool IsTryLockSupported() {
|
|
||||||
OSVERSIONINFOEX osvi;
|
|
||||||
BOOL bOsVersionInfoEx;
|
|
||||||
|
|
||||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
||||||
|
|
||||||
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
|
|
||||||
{
|
|
||||||
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
|
|
||||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
|
||||||
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() NOT supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests for Windows NT product family.
|
|
||||||
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion >= 4) {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() SUPPORTED" << std::endl;
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() NOT supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Mutex::Mutex() {
|
|
||||||
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 7
|
|
||||||
std::cout << "Constructing Mutex" << std::endl;
|
|
||||||
#endif
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
InitializeCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
pthread_mutexattr_init(&attr);
|
|
||||||
#if defined(__CYGWIN__) || defined(__APPLE__) || defined(FREEBSD)
|
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
#else
|
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
|
||||||
#endif
|
|
||||||
pthread_mutex_init(&CSMutex, &attr);
|
|
||||||
pthread_mutexattr_destroy(&attr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::~Mutex() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
DeleteCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::lock() {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 5
|
|
||||||
if (!trylock()) {
|
|
||||||
std::cout << "Locking Mutex: Having to wait" << std::endl;
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_lock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_lock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Mutex::trylock() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#if(_WIN32_WINNT >= 0x0400)
|
|
||||||
if (TrylockSupported)
|
|
||||||
return TryEnterCriticalSection(&CSMutex);
|
|
||||||
else {
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return (pthread_mutex_trylock(&CSMutex) == 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::unlock() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_unlock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LockMutex::LockMutex(Mutex* in_mut, bool iLock) {
|
|
||||||
mut = in_mut;
|
|
||||||
locked = iLock;
|
|
||||||
if (locked) {
|
|
||||||
mut->lock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LockMutex::~LockMutex() {
|
|
||||||
if (locked) {
|
|
||||||
mut->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockMutex::unlock() {
|
|
||||||
if (locked)
|
|
||||||
mut->unlock();
|
|
||||||
locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockMutex::lock() {
|
|
||||||
if (!locked)
|
|
||||||
mut->lock();
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/types.h"
|
|
||||||
#include "common/platform/posix/include_pthreads.h"
|
|
||||||
#include "common/platform/win/include_windows.h"
|
|
||||||
|
|
||||||
class Mutex {
|
|
||||||
public:
|
|
||||||
Mutex();
|
|
||||||
~Mutex();
|
|
||||||
|
|
||||||
void lock();
|
|
||||||
void unlock();
|
|
||||||
bool trylock();
|
|
||||||
protected:
|
|
||||||
private:
|
|
||||||
#if defined _WINDOWS
|
|
||||||
CRITICAL_SECTION CSMutex;
|
|
||||||
#else
|
|
||||||
pthread_mutex_t CSMutex;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class LockMutex {
|
|
||||||
public:
|
|
||||||
LockMutex(Mutex* in_mut, bool iLock = true);
|
|
||||||
~LockMutex();
|
|
||||||
void unlock();
|
|
||||||
void lock();
|
|
||||||
private:
|
|
||||||
bool locked;
|
|
||||||
Mutex* mut;
|
|
||||||
};
|
|
||||||
+10
-6
@@ -18,7 +18,6 @@
|
|||||||
#include "mysql_stmt.h"
|
#include "mysql_stmt.h"
|
||||||
|
|
||||||
#include "common/eqemu_logsys.h"
|
#include "common/eqemu_logsys.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
@@ -31,14 +30,19 @@ void PreparedStmt::StmtDeleter::operator()(MYSQL_STMT* stmt) noexcept
|
|||||||
// The connection must be locked when closing the stmt to avoid mysql errors
|
// The connection must be locked when closing the stmt to avoid mysql errors
|
||||||
// in case another thread tries to use it during the close. If the mutex is
|
// in case another thread tries to use it during the close. If the mutex is
|
||||||
// changed to one that throws then exceptions need to be caught here.
|
// changed to one that throws then exceptions need to be caught here.
|
||||||
LockMutex lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts)
|
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, std::mutex& mutex, StmtOptions opts)
|
||||||
: m_stmt(mysql_stmt_init(&mysql), { mutex }), m_query(std::move(query)), m_mutex(mutex), m_options(opts)
|
: m_stmt(mysql_stmt_init(&mysql), { mutex })
|
||||||
|
, m_query(std::move(query))
|
||||||
|
, m_options(opts)
|
||||||
|
, m_mutex(mutex)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
||||||
{
|
{
|
||||||
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
||||||
@@ -186,7 +190,7 @@ void PreparedStmt::CheckArgs(size_t argc)
|
|||||||
StmtResult PreparedStmt::DoExecute()
|
StmtResult PreparedStmt::DoExecute()
|
||||||
{
|
{
|
||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+6
-3
@@ -17,10 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -183,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, Mutex* mutex, StmtOptions opts = {});
|
PreparedStmt(MYSQL& mysql, std::string query, std::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; }
|
||||||
@@ -219,7 +221,8 @@ private:
|
|||||||
|
|
||||||
struct StmtDeleter
|
struct StmtDeleter
|
||||||
{
|
{
|
||||||
Mutex* mutex = nullptr;
|
std::mutex& mutex;
|
||||||
|
|
||||||
void operator()(MYSQL_STMT* stmt) noexcept;
|
void operator()(MYSQL_STMT* stmt) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -232,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;
|
||||||
Mutex* m_mutex = nullptr; // connection mutex
|
std::mutex& m_mutex; // connection mutex
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mysql
|
} // namespace mysql
|
||||||
|
|||||||
+26
-23
@@ -142,10 +142,12 @@ RegularOpcodeManager::~RegularOpcodeManager() {
|
|||||||
safe_delete_array(eq_to_emu);
|
safe_delete_array(eq_to_emu);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors) {
|
bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors)
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(MOpcodes);
|
||||||
|
|
||||||
NormalMemStrategy s;
|
NormalMemStrategy s;
|
||||||
s.it = this;
|
s.it = this;
|
||||||
MOpcodes.lock();
|
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
eq_to_emu = new EmuOpcode[MAX_EQ_OPCODE];
|
eq_to_emu = new EmuOpcode[MAX_EQ_OPCODE];
|
||||||
@@ -158,32 +160,30 @@ bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors)
|
|||||||
memset(emu_to_eq, 0, sizeof(uint16)*_maxEmuOpcode);
|
memset(emu_to_eq, 0, sizeof(uint16)*_maxEmuOpcode);
|
||||||
|
|
||||||
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
||||||
MOpcodes.unlock();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegularOpcodeManager::ReloadOpcodes(const char *filename, bool report_errors) {
|
bool RegularOpcodeManager::ReloadOpcodes(const char* filename, bool report_errors)
|
||||||
if(!loaded)
|
{
|
||||||
return(LoadOpcodes(filename));
|
if (!loaded)
|
||||||
|
return LoadOpcodes(filename);
|
||||||
|
|
||||||
|
std::scoped_lock lock(MOpcodes);
|
||||||
|
|
||||||
NormalMemStrategy s;
|
NormalMemStrategy s;
|
||||||
s.it = this;
|
s.it = this;
|
||||||
MOpcodes.lock();
|
|
||||||
|
|
||||||
memset(eq_to_emu, 0, sizeof(uint16)*MAX_EQ_OPCODE);
|
memset(eq_to_emu, 0, sizeof(uint16) * MAX_EQ_OPCODE);
|
||||||
|
return LoadOpcodesFile(filename, &s, report_errors);
|
||||||
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
|
||||||
|
|
||||||
MOpcodes.unlock();
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
||||||
//opcode is checked for validity in GetEQOpcode
|
//opcode is checked for validity in GetEQOpcode
|
||||||
uint16 res;
|
uint16 res;
|
||||||
MOpcodes.lock();
|
{
|
||||||
res = emu_to_eq[emu_op];
|
std::scoped_lock lock(MOpcodes);
|
||||||
MOpcodes.unlock();
|
res = emu_to_eq[emu_op];
|
||||||
|
}
|
||||||
|
|
||||||
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
||||||
|
|
||||||
@@ -193,15 +193,18 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
|||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuOpcode RegularOpcodeManager::EQToEmu(const uint16 eq_op) {
|
EmuOpcode RegularOpcodeManager::EQToEmu(const uint16 eq_op)
|
||||||
|
{
|
||||||
//opcode is checked for validity in GetEmuOpcode
|
//opcode is checked for validity in GetEmuOpcode
|
||||||
//Disabled since current live EQ uses the entire uint16 bitspace for opcodes
|
//Disabled since current live EQ uses the entire uint16 bitspace for opcodes
|
||||||
// if(eq_op > MAX_EQ_OPCODE)
|
// if(eq_op > MAX_EQ_OPCODE)
|
||||||
// return(OP_Unknown);
|
// return(OP_Unknown);
|
||||||
EmuOpcode res;
|
EmuOpcode res;
|
||||||
MOpcodes.lock();
|
{
|
||||||
res = eq_to_emu[eq_op];
|
std::scoped_lock lock(MOpcodes);
|
||||||
MOpcodes.unlock();
|
res = eq_to_emu[eq_op];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_TRANSLATE
|
#ifdef DEBUG_TRANSLATE
|
||||||
fprintf(stderr, "M Translate EQ 0x%.4x to Emu %s (%d)\n", eq_op, OpcodeNames[res], res);
|
fprintf(stderr, "M Translate EQ 0x%.4x to Emu %s (%d)\n", eq_op, OpcodeNames[res], res);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+2
-2
@@ -18,10 +18,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/emu_opcodes.h"
|
#include "common/emu_opcodes.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
//enable the use of shared mem opcodes for world and zone only
|
//enable the use of shared mem opcodes for world and zone only
|
||||||
#ifdef ZONE
|
#ifdef ZONE
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool loaded; //true if all opcodes loaded
|
bool loaded; //true if all opcodes loaded
|
||||||
Mutex MOpcodes; //this only protects the local machine
|
std::mutex MOpcodes; //this only protects the local machine
|
||||||
//in a shared manager, this dosent protect others
|
//in a shared manager, this dosent protect others
|
||||||
|
|
||||||
static bool LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors);
|
static bool LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors);
|
||||||
|
|||||||
@@ -20,9 +20,12 @@
|
|||||||
#include "common/eqemu_config.h"
|
#include "common/eqemu_config.h"
|
||||||
#include "common/repositories/zone_repository.h"
|
#include "common/repositories/zone_repository.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
Database db;
|
Database db;
|
||||||
Database db2;
|
Database db2;
|
||||||
|
|
||||||
@@ -60,8 +63,6 @@ void WorldserverCLI::TestDatabaseConcurrency(int argc, char **argv, argh::parser
|
|||||||
|
|
||||||
LogInfo("Database test");
|
LogInfo("Database test");
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
auto c = EQEmuConfig::get();
|
auto c = EQEmuConfig::get();
|
||||||
LogInfo("Connecting to MySQL");
|
LogInfo("Connecting to MySQL");
|
||||||
if (!db.Connect(
|
if (!db.Connect(
|
||||||
@@ -75,19 +76,19 @@ void WorldserverCLI::TestDatabaseConcurrency(int argc, char **argv, argh::parser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.SetMutex(mutex);
|
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
||||||
|
|
||||||
|
db.SetMutex(sharedMutex);
|
||||||
|
|
||||||
db2.SetMySQL(db);
|
db2.SetMySQL(db);
|
||||||
|
|
||||||
db2.SetMutex(mutex);
|
db2.SetMutex(sharedMutex);
|
||||||
|
|
||||||
std::thread(DatabaseTest).detach();
|
std::thread(DatabaseTest).detach();
|
||||||
std::thread(DatabaseTest).detach();
|
std::thread(DatabaseTest).detach();
|
||||||
std::thread(DatabaseTestSecondConnection).detach();
|
std::thread(DatabaseTestSecondConnection).detach();
|
||||||
|
|
||||||
while (!stop) {
|
while (!stop) {
|
||||||
|
std::this_thread::sleep_for(0s);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/event/timer.h"
|
#include "common/event/timer.h"
|
||||||
#include "common/linked_list.h"
|
#include "common/linked_list.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/net/servertalk_client_connection.h"
|
#include "common/net/servertalk_client_connection.h"
|
||||||
#include "common/net/servertalk_legacy_client_connection.h"
|
#include "common/net/servertalk_legacy_client_connection.h"
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
#include "common/servertalk.h"
|
#include "common/servertalk.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
|||||||
@@ -49,8 +49,6 @@
|
|||||||
|
|
||||||
extern WorldConfig Config;
|
extern WorldConfig Config;
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, const char *func, std::string message)
|
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, const char *func, std::string message)
|
||||||
{
|
{
|
||||||
// we don't want to loop up with chat messages
|
// we don't want to loop up with chat messages
|
||||||
@@ -180,11 +178,13 @@ bool WorldBoot::LoadDatabaseConnections()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
|
|
||||||
// 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
|
||||||
database.SetMutex(mutex);
|
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
||||||
content_db.SetMutex(mutex);
|
database.SetMutex(sharedMutex);
|
||||||
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -634,7 +634,6 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
|
|||||||
|
|
||||||
void WorldBoot::Shutdown()
|
void WorldBoot::Shutdown()
|
||||||
{
|
{
|
||||||
safe_delete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
|
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
|
||||||
|
|||||||
+4
-6
@@ -26,7 +26,6 @@
|
|||||||
#include "common/guilds.h"
|
#include "common/guilds.h"
|
||||||
#include "common/memory_mapped_file.h"
|
#include "common/memory_mapped_file.h"
|
||||||
#include "common/misc.h"
|
#include "common/misc.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/net/eqstream.h"
|
#include "common/net/eqstream.h"
|
||||||
#include "common/opcodemgr.h"
|
#include "common/opcodemgr.h"
|
||||||
#include "common/patches/patches.h"
|
#include "common/patches/patches.h"
|
||||||
@@ -216,8 +215,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
LogInfo("Connecting to MySQL");
|
LogInfo("Connecting to MySQL");
|
||||||
if (!database.Connect(
|
if (!database.Connect(
|
||||||
Config->DatabaseHost.c_str(),
|
Config->DatabaseHost.c_str(),
|
||||||
@@ -245,11 +242,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
|
|
||||||
// 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
|
||||||
database.SetMutex(mutex);
|
std::shared_ptr<std::mutex> sharedMutex = std::make_shared<std::mutex>();
|
||||||
content_db.SetMutex(mutex);
|
database.SetMutex(sharedMutex);
|
||||||
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//rules:
|
//rules:
|
||||||
@@ -661,7 +660,6 @@ int main(int argc, char **argv)
|
|||||||
LogInfo("Proper zone shutdown complete.");
|
LogInfo("Proper zone shutdown complete.");
|
||||||
EQEmuLogSys::Instance()->CloseFileLogs();
|
EQEmuLogSys::Instance()->CloseFileLogs();
|
||||||
|
|
||||||
safe_delete(mutex);
|
|
||||||
safe_delete(QServ);
|
safe_delete(QServ);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+9
-8
@@ -135,10 +135,11 @@ void PetitionList::AddPetition(Petition* pet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Return Values: 0 = Ok ; -1 = Error deleting petition.
|
//Return Values: 0 = Ok ; -1 = Error deleting petition.
|
||||||
int PetitionList::DeletePetition(uint32 petnumber) {
|
int PetitionList::DeletePetition(uint32 petnumber)
|
||||||
|
{
|
||||||
LinkedListIterator<Petition*> iterator(list);
|
LinkedListIterator<Petition*> iterator(list);
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
LockMutex lock(&PList_Mutex);
|
std::scoped_lock lock(PList_Mutex);
|
||||||
while(iterator.MoreElements()) {
|
while(iterator.MoreElements()) {
|
||||||
if (iterator.GetData()->GetID() == petnumber) {
|
if (iterator.GetData()->GetID() == petnumber) {
|
||||||
database.DeletePetitionFromDB(iterator.GetData());
|
database.DeletePetitionFromDB(iterator.GetData());
|
||||||
@@ -179,18 +180,18 @@ void PetitionList::ClearPetitions() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetitionList::ReadDatabase() {
|
void PetitionList::ReadDatabase()
|
||||||
LockMutex lock(&PList_Mutex);
|
{
|
||||||
|
std::scoped_lock lock(PList_Mutex);
|
||||||
ClearPetitions();
|
ClearPetitions();
|
||||||
database.RefreshPetitionsFromDB();
|
database.RefreshPetitionsFromDB();
|
||||||
UpdateGMQueue();
|
UpdateGMQueue();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetitionList::UpdatePetition(Petition* pet) {
|
void PetitionList::UpdatePetition(Petition* pet)
|
||||||
LockMutex lock(&PList_Mutex);
|
{
|
||||||
|
std::scoped_lock lock(PList_Mutex);
|
||||||
database.UpdatePetitionToDB(pet);
|
database.UpdatePetitionToDB(pet);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
|
void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
|
||||||
|
|||||||
+3
-6
@@ -18,12 +18,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/linked_list.h"
|
#include "common/linked_list.h"
|
||||||
#include "common/misc_functions.h"
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "common/zone_store.h"
|
|
||||||
#include "zone/client.h"
|
#include <mutex>
|
||||||
#include "zone/zonedb.h"
|
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
@@ -118,5 +115,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
LinkedList<Petition*> list;
|
LinkedList<Petition*> list;
|
||||||
Mutex PList_Mutex;
|
std::mutex PList_Mutex;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user