fix for 45337 and some other little things
This commit is contained in:
parent
f3057efd7d
commit
fe1ebfe7bb
|
@ -55,6 +55,10 @@ static cell AMX_NATIVE_CALL SQL_MakeDbTuple(AMX *amx, cell *params)
|
||||||
sql->user = strdup(MF_GetAmxString(amx, params[2], 0, &len));
|
sql->user = strdup(MF_GetAmxString(amx, params[2], 0, &len));
|
||||||
sql->pass = strdup(MF_GetAmxString(amx, params[3], 0, &len));
|
sql->pass = strdup(MF_GetAmxString(amx, params[3], 0, &len));
|
||||||
sql->db = strdup(MF_GetAmxString(amx, params[4], 0, &len));
|
sql->db = strdup(MF_GetAmxString(amx, params[4], 0, &len));
|
||||||
|
if (params[0] / sizeof(cell) >= 5)
|
||||||
|
{
|
||||||
|
sql->max_timeout = static_cast<unsigned int>(params[5]);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int num = MakeHandle(sql, Handle_Connection, FreeConnection);
|
unsigned int num = MakeHandle(sql, Handle_Connection, FreeConnection);
|
||||||
|
|
||||||
|
@ -87,11 +91,12 @@ static cell AMX_NATIVE_CALL SQL_Connect(AMX *amx, cell *params)
|
||||||
nfo.pass = sql->pass;
|
nfo.pass = sql->pass;
|
||||||
nfo.port = sql->port;
|
nfo.port = sql->port;
|
||||||
nfo.host = sql->host;
|
nfo.host = sql->host;
|
||||||
|
nfo.max_timeout = sql->max_timeout;
|
||||||
|
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|
||||||
IDatabase *pDb = g_Mysql.Connect(&nfo, &errcode, buffer, sizeof(buffer)-1);
|
IDatabase *pDb = g_Mysql.Connect2(&nfo, &errcode, buffer, sizeof(buffer)-1);
|
||||||
|
|
||||||
if (!pDb)
|
if (!pDb)
|
||||||
{
|
{
|
||||||
|
@ -378,13 +383,15 @@ static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
||||||
|
|
||||||
if (!qInfo || !qInfo->pQuery)
|
if (!qInfo || (!qInfo->pQuery && !qInfo->opt_ptr))
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MF_SetAmxString(amx, params[2], qInfo->pQuery->GetQueryString(), params[3]);
|
const char *ptr = qInfo->pQuery ? qInfo->pQuery->GetQueryString() : qInfo->opt_ptr;
|
||||||
|
|
||||||
|
return MF_SetAmxString(amx, params[2], ptr, params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)
|
||||||
|
|
|
@ -134,11 +134,13 @@ namespace SourceMod
|
||||||
|
|
||||||
struct DatabaseInfo
|
struct DatabaseInfo
|
||||||
{
|
{
|
||||||
|
DatabaseInfo() : max_timeout(0) { };
|
||||||
const char *host;
|
const char *host;
|
||||||
const char *database;
|
const char *database;
|
||||||
const char *user;
|
const char *user;
|
||||||
const char *pass;
|
const char *pass;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
|
unsigned int max_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ISQLDriver
|
class ISQLDriver
|
||||||
|
@ -147,6 +149,8 @@ namespace SourceMod
|
||||||
virtual ~ISQLDriver() { };
|
virtual ~ISQLDriver() { };
|
||||||
public:
|
public:
|
||||||
virtual IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
|
virtual IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
|
||||||
|
//Supports the timeout clause
|
||||||
|
virtual IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
|
||||||
virtual const char *NameString() =0;
|
virtual const char *NameString() =0;
|
||||||
virtual bool IsCompatDriver(const char *namestring) =0;
|
virtual bool IsCompatDriver(const char *namestring) =0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,16 @@ const char *MysqlDriver::NameString()
|
||||||
}
|
}
|
||||||
|
|
||||||
IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
|
IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
|
||||||
|
{
|
||||||
|
return _Connect(info, errcode, error, maxlength, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDatabase *MysqlDriver::Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
|
||||||
|
{
|
||||||
|
return _Connect(info, errcode, error, maxlength, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDatabase *MysqlDriver::_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout)
|
||||||
{
|
{
|
||||||
MYSQL *mysql = mysql_init(NULL);
|
MYSQL *mysql = mysql_init(NULL);
|
||||||
|
|
||||||
|
@ -35,6 +45,11 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_timeout && info->max_timeout)
|
||||||
|
{
|
||||||
|
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&(info->max_timeout));
|
||||||
|
}
|
||||||
|
|
||||||
if (mysql_real_connect(mysql,
|
if (mysql_real_connect(mysql,
|
||||||
info->host,
|
info->host,
|
||||||
info->user,
|
info->user,
|
||||||
|
@ -45,9 +60,13 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
|
||||||
0) == NULL)
|
0) == NULL)
|
||||||
{
|
{
|
||||||
if (errcode)
|
if (errcode)
|
||||||
|
{
|
||||||
*errcode = mysql_errno(mysql);
|
*errcode = mysql_errno(mysql);
|
||||||
|
}
|
||||||
if (error && maxlength)
|
if (error && maxlength)
|
||||||
|
{
|
||||||
snprintf(error, maxlength, "%s", mysql_error(mysql));
|
snprintf(error, maxlength, "%s", mysql_error(mysql));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,11 @@ namespace SourceMod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
|
IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
|
||||||
|
IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
|
||||||
const char *NameString();
|
const char *NameString();
|
||||||
bool IsCompatDriver(const char *namestring);
|
bool IsCompatDriver(const char *namestring);
|
||||||
|
public:
|
||||||
|
IDatabase *_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
|
|
||||||
struct AmxQueryInfo
|
struct AmxQueryInfo
|
||||||
{
|
{
|
||||||
|
AmxQueryInfo() : opt_ptr(NULL) { };
|
||||||
IQuery *pQuery;
|
IQuery *pQuery;
|
||||||
QueryInfo info;
|
QueryInfo info;
|
||||||
char error[255];
|
char error[255];
|
||||||
|
char *opt_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HandleType
|
enum HandleType
|
||||||
|
@ -32,6 +34,7 @@ struct SQL_Connection
|
||||||
char *pass;
|
char *pass;
|
||||||
char *db;
|
char *db;
|
||||||
int port;
|
int port;
|
||||||
|
unsigned int max_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*FREEHANDLE)(void *, unsigned int);
|
typedef void (*FREEHANDLE)(void *, unsigned int);
|
||||||
|
|
|
@ -58,7 +58,7 @@ static cell AMX_NATIVE_CALL SQL_ThreadQuery(AMX *amx, cell *params)
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
const char *handler = MF_GetAmxString(amx, params[2], 0, &len);
|
const char *handler = MF_GetAmxString(amx, params[2], 0, &len);
|
||||||
int fwd = MF_RegisterSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_ARRAY, FP_CELL, FP_DONE);
|
int fwd = MF_RegisterSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE);
|
||||||
if (fwd < 1)
|
if (fwd < 1)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Function not found: %s", handler);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Function not found: %s", handler);
|
||||||
|
@ -76,7 +76,7 @@ static cell AMX_NATIVE_CALL SQL_ThreadQuery(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
g_QueueLock->Unlock();
|
g_QueueLock->Unlock();
|
||||||
|
|
||||||
kmThread->SetInfo(cn->host, cn->user, cn->pass, cn->db, cn->port);
|
kmThread->SetInfo(cn->host, cn->user, cn->pass, cn->db, cn->port, cn->max_timeout);
|
||||||
kmThread->SetForward(fwd);
|
kmThread->SetForward(fwd);
|
||||||
kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
|
kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
|
||||||
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
|
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
|
||||||
|
@ -126,13 +126,15 @@ void MysqlThread::SetForward(int forward)
|
||||||
m_fwd = forward;
|
m_fwd = forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MysqlThread::SetInfo(const char *host, const char *user, const char *pass, const char *db, int port)
|
void MysqlThread::SetInfo(const char *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout)
|
||||||
{
|
{
|
||||||
m_host.assign(host);
|
m_host.assign(host);
|
||||||
m_user.assign(user);
|
m_user.assign(user);
|
||||||
m_pass.assign(pass);
|
m_pass.assign(pass);
|
||||||
m_db.assign(db);
|
m_db.assign(db);
|
||||||
|
m_max_timeout = m_max_timeout;
|
||||||
m_port = port;
|
m_port = port;
|
||||||
|
m_qrInfo.queue_time = gpGlobals->time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MysqlThread::SetQuery(const char *query)
|
void MysqlThread::SetQuery(const char *query)
|
||||||
|
@ -149,10 +151,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
|
||||||
info.user = m_user.c_str();
|
info.user = m_user.c_str();
|
||||||
info.host = m_host.c_str();
|
info.host = m_host.c_str();
|
||||||
info.port = m_port;
|
info.port = m_port;
|
||||||
|
info.max_timeout = m_max_timeout;
|
||||||
|
|
||||||
|
float save_time = m_qrInfo.queue_time;
|
||||||
|
|
||||||
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
|
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
|
||||||
|
|
||||||
IDatabase *pDatabase = g_Mysql.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
|
m_qrInfo.queue_time = save_time;
|
||||||
|
|
||||||
|
IDatabase *pDatabase = g_Mysql.Connect2(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
|
||||||
IQuery *pQuery = NULL;
|
IQuery *pQuery = NULL;
|
||||||
if (!pDatabase)
|
if (!pDatabase)
|
||||||
{
|
{
|
||||||
|
@ -172,14 +179,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
|
||||||
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
|
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
|
||||||
{
|
{
|
||||||
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
|
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
|
||||||
m_qrInfo.amxinfo.pQuery = pQuery;
|
|
||||||
m_qrInfo.amxinfo.info.rs = &m_atomicResult;
|
m_qrInfo.amxinfo.info.rs = &m_atomicResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQuery)
|
||||||
|
{
|
||||||
|
m_qrInfo.amxinfo.pQuery = pQuery;
|
||||||
} else {
|
} else {
|
||||||
if (pQuery)
|
m_qrInfo.amxinfo.opt_ptr = new char[m_query.size() + 1];
|
||||||
{
|
strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.c_str());
|
||||||
pQuery->FreeHandle();
|
|
||||||
}
|
|
||||||
pQuery = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDatabase)
|
if (pDatabase)
|
||||||
|
@ -231,31 +239,37 @@ void MysqlThread::Execute()
|
||||||
} else if (!m_qrInfo.query_success) {
|
} else if (!m_qrInfo.query_success) {
|
||||||
state = -1;
|
state = -1;
|
||||||
}
|
}
|
||||||
|
float diff = gpGlobals->time - m_qrInfo.queue_time;
|
||||||
|
cell c_diff = amx_ftoc(diff);
|
||||||
|
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
|
||||||
if (state != 0)
|
if (state != 0)
|
||||||
{
|
{
|
||||||
MF_ExecuteForward(m_fwd,
|
MF_ExecuteForward(m_fwd,
|
||||||
(cell)state,
|
(cell)state,
|
||||||
(cell)0,
|
(cell)hndl,
|
||||||
m_qrInfo.amxinfo.error,
|
m_qrInfo.amxinfo.error,
|
||||||
m_qrInfo.amxinfo.info.errorcode,
|
m_qrInfo.amxinfo.info.errorcode,
|
||||||
data_addr,
|
data_addr,
|
||||||
m_datalen);
|
m_datalen,
|
||||||
|
c_diff);
|
||||||
} else {
|
} else {
|
||||||
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
|
|
||||||
MF_ExecuteForward(m_fwd,
|
MF_ExecuteForward(m_fwd,
|
||||||
(cell)0,
|
(cell)0,
|
||||||
(cell)hndl,
|
(cell)hndl,
|
||||||
"",
|
"",
|
||||||
(cell)0,
|
(cell)0,
|
||||||
data_addr,
|
data_addr,
|
||||||
m_datalen);
|
m_datalen,
|
||||||
/* this should always be true I think */
|
c_diff);
|
||||||
if (m_qrInfo.amxinfo.pQuery)
|
|
||||||
{
|
|
||||||
m_qrInfo.amxinfo.pQuery->FreeHandle();
|
|
||||||
}
|
|
||||||
FreeHandle(hndl);
|
|
||||||
}
|
}
|
||||||
|
FreeHandle(hndl);
|
||||||
|
if (m_qrInfo.amxinfo.pQuery)
|
||||||
|
{
|
||||||
|
m_qrInfo.amxinfo.pQuery->FreeHandle();
|
||||||
|
m_qrInfo.amxinfo.pQuery = NULL;
|
||||||
|
}
|
||||||
|
delete [] m_qrInfo.amxinfo.opt_ptr;
|
||||||
|
m_qrInfo.amxinfo.opt_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct QueuedResultInfo
|
||||||
AmxQueryInfo amxinfo;
|
AmxQueryInfo amxinfo;
|
||||||
bool connect_success;
|
bool connect_success;
|
||||||
bool query_success;
|
bool query_success;
|
||||||
|
float queue_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AtomicResult :
|
class AtomicResult :
|
||||||
|
@ -59,7 +60,7 @@ public:
|
||||||
MysqlThread();
|
MysqlThread();
|
||||||
~MysqlThread();
|
~MysqlThread();
|
||||||
public:
|
public:
|
||||||
void SetInfo(const char *host, const char *user, const char *pass, const char *db, int port);
|
void SetInfo(const char *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout);
|
||||||
void SetQuery(const char *query);
|
void SetQuery(const char *query);
|
||||||
void SetCellData(cell data[], ucell len);
|
void SetCellData(cell data[], ucell len);
|
||||||
void SetForward(int forward);
|
void SetForward(int forward);
|
||||||
|
@ -74,6 +75,7 @@ private:
|
||||||
SourceHook::String m_user;
|
SourceHook::String m_user;
|
||||||
SourceHook::String m_pass;
|
SourceHook::String m_pass;
|
||||||
SourceHook::String m_db;
|
SourceHook::String m_db;
|
||||||
|
unsigned int m_max_timeout;
|
||||||
int m_port;
|
int m_port;
|
||||||
cell *m_data;
|
cell *m_data;
|
||||||
ucell m_datalen;
|
ucell m_datalen;
|
||||||
|
|
|
@ -382,13 +382,16 @@ static cell AMX_NATIVE_CALL SQL_FieldNumToName(AMX *amx, cell *params)
|
||||||
static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
||||||
if (!qInfo)
|
|
||||||
|
if (!qInfo || (!qInfo->pQuery && !qInfo->opt_ptr))
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MF_SetAmxString(amx, params[2], qInfo->pQuery->GetQueryString(), params[3]);
|
const char *ptr = qInfo->pQuery ? qInfo->pQuery->GetQueryString() : qInfo->opt_ptr;
|
||||||
|
|
||||||
|
return MF_SetAmxString(amx, params[2], ptr, params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
namespace SourceHook
|
namespace SourceHook
|
||||||
{
|
{
|
||||||
|
|
||||||
//This class is from CSDM for AMX Mod X
|
//This class is from CSDM for AMX Mod X
|
||||||
/*
|
/*
|
||||||
A circular, doubly-linked list with one sentinel node
|
A circular, doubly-linked list with one sentinel node
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
|
|
||||||
struct AmxQueryInfo
|
struct AmxQueryInfo
|
||||||
{
|
{
|
||||||
|
AmxQueryInfo() : opt_ptr(NULL) { };
|
||||||
IQuery *pQuery;
|
IQuery *pQuery;
|
||||||
QueryInfo info;
|
QueryInfo info;
|
||||||
char error[255];
|
char error[255];
|
||||||
|
char *opt_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HandleType
|
enum HandleType
|
||||||
|
|
|
@ -54,6 +54,9 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
||||||
/**
|
/**
|
||||||
* Check number of items in the queue
|
* Check number of items in the queue
|
||||||
*/
|
*/
|
||||||
|
m_StateLock->Lock();
|
||||||
|
this_state = m_state;
|
||||||
|
m_StateLock->Unlock();
|
||||||
if (this_state != Worker_Stopped)
|
if (this_state != Worker_Stopped)
|
||||||
{
|
{
|
||||||
m_QueueLock->Lock();
|
m_QueueLock->Lock();
|
||||||
|
@ -65,6 +68,11 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
||||||
*/
|
*/
|
||||||
m_Waiting = true;
|
m_Waiting = true;
|
||||||
m_QueueLock->Unlock();
|
m_QueueLock->Unlock();
|
||||||
|
/* first check if we should end again */
|
||||||
|
if (this_state == Worker_Stopped)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
m_AddSignal->Wait();
|
m_AddSignal->Wait();
|
||||||
m_Waiting = false;
|
m_Waiting = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,7 +88,9 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
||||||
{
|
{
|
||||||
//wait until the lock is cleared.
|
//wait until the lock is cleared.
|
||||||
if (this_state == Worker_Paused)
|
if (this_state == Worker_Paused)
|
||||||
|
{
|
||||||
m_PauseSignal->Wait();
|
m_PauseSignal->Wait();
|
||||||
|
}
|
||||||
if (this_state == Worker_Stopped)
|
if (this_state == Worker_Stopped)
|
||||||
{
|
{
|
||||||
//if we're supposed to flush cleanrly,
|
//if we're supposed to flush cleanrly,
|
||||||
|
@ -187,9 +197,12 @@ bool ThreadWorker::Stop(bool flush_cancel)
|
||||||
{
|
{
|
||||||
Unpause();
|
Unpause();
|
||||||
} else {
|
} else {
|
||||||
m_AddSignal->Signal();
|
m_QueueLock->Lock();
|
||||||
Pause();
|
if (m_Waiting)
|
||||||
Unpause();
|
{
|
||||||
|
m_AddSignal->Signal();
|
||||||
|
}
|
||||||
|
m_QueueLock->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
me->WaitForThread();
|
me->WaitForThread();
|
||||||
|
|
|
@ -97,7 +97,7 @@ IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *par
|
||||||
|
|
||||||
IEventSignal *WinThreader::MakeEventSignal()
|
IEventSignal *WinThreader::MakeEventSignal()
|
||||||
{
|
{
|
||||||
HANDLE event = CreateEventA(NULL, TRUE, TRUE, NULL);
|
HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
if (!event)
|
if (!event)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -275,7 +275,6 @@ WinThreader::WinEvent::~WinEvent()
|
||||||
void WinThreader::WinEvent::Wait()
|
void WinThreader::WinEvent::Wait()
|
||||||
{
|
{
|
||||||
WaitForSingleObject(m_event, INFINITE);
|
WaitForSingleObject(m_event, INFINITE);
|
||||||
ResetEvent(m_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinThreader::WinEvent::Signal()
|
void WinThreader::WinEvent::Signal()
|
||||||
|
|
|
@ -129,6 +129,7 @@ void MysqlThread::SetForward(int forward)
|
||||||
void MysqlThread::SetInfo(const char *db)
|
void MysqlThread::SetInfo(const char *db)
|
||||||
{
|
{
|
||||||
m_db.assign(db);
|
m_db.assign(db);
|
||||||
|
m_qrInfo.queue_time = gpGlobals->time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MysqlThread::SetQuery(const char *query)
|
void MysqlThread::SetQuery(const char *query)
|
||||||
|
@ -146,8 +147,12 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
|
||||||
info.host = "";
|
info.host = "";
|
||||||
info.port = 0;
|
info.port = 0;
|
||||||
|
|
||||||
|
float save_time = m_qrInfo.queue_time;
|
||||||
|
|
||||||
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
|
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
|
||||||
|
|
||||||
|
m_qrInfo.queue_time = save_time;
|
||||||
|
|
||||||
IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
|
IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
|
||||||
IQuery *pQuery = NULL;
|
IQuery *pQuery = NULL;
|
||||||
if (!pDatabase)
|
if (!pDatabase)
|
||||||
|
@ -168,15 +173,17 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
|
||||||
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
|
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
|
||||||
{
|
{
|
||||||
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
|
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
|
||||||
m_qrInfo.amxinfo.pQuery = NULL;
|
|
||||||
m_qrInfo.amxinfo.info.rs = &m_atomicResult;
|
m_qrInfo.amxinfo.info.rs = &m_atomicResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery)
|
if (pQuery)
|
||||||
{
|
{
|
||||||
pQuery->FreeHandle();
|
m_qrInfo.amxinfo.pQuery = pQuery;
|
||||||
pQuery = NULL;
|
} else {
|
||||||
|
m_qrInfo.amxinfo.opt_ptr = new char[m_query.size() + 1];
|
||||||
|
strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDatabase)
|
if (pDatabase)
|
||||||
{
|
{
|
||||||
pDatabase->FreeHandle();
|
pDatabase->FreeHandle();
|
||||||
|
@ -226,26 +233,37 @@ void MysqlThread::Execute()
|
||||||
} else if (!m_qrInfo.query_success) {
|
} else if (!m_qrInfo.query_success) {
|
||||||
state = -1;
|
state = -1;
|
||||||
}
|
}
|
||||||
|
float diff = gpGlobals->time - m_qrInfo.queue_time;
|
||||||
|
cell c_diff = amx_ftoc(diff);
|
||||||
|
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
|
||||||
if (state != 0)
|
if (state != 0)
|
||||||
{
|
{
|
||||||
MF_ExecuteForward(m_fwd,
|
MF_ExecuteForward(m_fwd,
|
||||||
(cell)state,
|
(cell)state,
|
||||||
(cell)0,
|
(cell)hndl,
|
||||||
m_qrInfo.amxinfo.error,
|
m_qrInfo.amxinfo.error,
|
||||||
m_qrInfo.amxinfo.info.errorcode,
|
m_qrInfo.amxinfo.info.errorcode,
|
||||||
data_addr,
|
data_addr,
|
||||||
m_datalen);
|
m_datalen,
|
||||||
|
c_diff);
|
||||||
} else {
|
} else {
|
||||||
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
|
|
||||||
MF_ExecuteForward(m_fwd,
|
MF_ExecuteForward(m_fwd,
|
||||||
(cell)0,
|
(cell)0,
|
||||||
(cell)hndl,
|
(cell)hndl,
|
||||||
"",
|
"",
|
||||||
(cell)0,
|
(cell)0,
|
||||||
data_addr,
|
data_addr,
|
||||||
m_datalen);
|
m_datalen,
|
||||||
FreeHandle(hndl);
|
c_diff);
|
||||||
}
|
}
|
||||||
|
FreeHandle(hndl);
|
||||||
|
if (m_qrInfo.amxinfo.pQuery)
|
||||||
|
{
|
||||||
|
m_qrInfo.amxinfo.pQuery->FreeHandle();
|
||||||
|
m_qrInfo.amxinfo.pQuery = NULL;
|
||||||
|
}
|
||||||
|
delete [] m_qrInfo.amxinfo.opt_ptr;
|
||||||
|
m_qrInfo.amxinfo.opt_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct QueuedResultInfo
|
||||||
AmxQueryInfo amxinfo;
|
AmxQueryInfo amxinfo;
|
||||||
bool connect_success;
|
bool connect_success;
|
||||||
bool query_success;
|
bool query_success;
|
||||||
|
float queue_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AtomicResult :
|
class AtomicResult :
|
||||||
|
|
|
@ -30,8 +30,12 @@ enum Handle
|
||||||
* !!NOTE!! I have seen most people think that this connects to the DB.
|
* !!NOTE!! I have seen most people think that this connects to the DB.
|
||||||
* Nowhere does it say this, and in fact it does not. It only caches
|
* Nowhere does it say this, and in fact it does not. It only caches
|
||||||
* the connection information, the host/user/pass/etc.
|
* the connection information, the host/user/pass/etc.
|
||||||
|
*
|
||||||
|
* The optional timeout parameter specifies how long connections should wait before
|
||||||
|
* giving up. If 0, the default (which is undefined) is used.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[]);
|
native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[], timeout=0);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,8 +78,9 @@ native Handle:SQL_PrepareQuery(Handle:db, const fmt[], {Float,_}:...);
|
||||||
* @param errnum - An error code, if any.
|
* @param errnum - An error code, if any.
|
||||||
* @param data - Data array you passed in.
|
* @param data - Data array you passed in.
|
||||||
* @param size - Size of the data array you passed in.
|
* @param size - Size of the data array you passed in.
|
||||||
|
* @param queuetime - Amount of gametime that passed while the query was resolving.
|
||||||
*
|
*
|
||||||
* public QueryHandler(failstate, Handle:query, error[], errnum, data[], size)
|
* public QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
|
||||||
*
|
*
|
||||||
* Note! The handle you pass in is a DB Tuple, NOT an active connection!
|
* Note! The handle you pass in is a DB Tuple, NOT an active connection!
|
||||||
* Note! The handle does not need to be freed.
|
* Note! The handle does not need to be freed.
|
||||||
|
|
|
@ -106,22 +106,22 @@ PrintQueryData(Handle:query)
|
||||||
/**
|
/**
|
||||||
* Handler for when a threaded query is resolved.
|
* Handler for when a threaded query is resolved.
|
||||||
*/
|
*/
|
||||||
public GetMyStuff(failstate, Handle:query, error[], errnum, data[], size)
|
public GetMyStuff(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
|
||||||
{
|
{
|
||||||
server_print("Resolved query %d at: %f", data[0], get_gametime())
|
server_print(" --> Resolved query %d, took %f seconds", data[0], queuetime)
|
||||||
if (failstate)
|
if (failstate)
|
||||||
{
|
{
|
||||||
if (failstate == TQUERY_CONNECT_FAILED)
|
if (failstate == TQUERY_CONNECT_FAILED)
|
||||||
{
|
{
|
||||||
server_print("Connection failed!")
|
server_print(" --> Connection failed!")
|
||||||
} else if (failstate == TQUERY_QUERY_FAILED) {
|
} else if (failstate == TQUERY_QUERY_FAILED) {
|
||||||
server_print("Query failed!")
|
server_print(" --> Query failed!")
|
||||||
}
|
}
|
||||||
server_print("Error code: %d (Message: ^"%s^")", errnum, error)
|
server_print(" --> Error code: %d (Message: ^"%s^")", errnum, error)
|
||||||
|
|
||||||
new querystring[1024]
|
new querystring[1024]
|
||||||
SQL_GetQueryString(query, querystring, 1023)
|
SQL_GetQueryString(query, querystring, 1023)
|
||||||
server_print("Original query: %s", querystring)
|
server_print(" --> Original query: %s", querystring)
|
||||||
} else {
|
} else {
|
||||||
PrintQueryData(query)
|
PrintQueryData(query)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user