Fix ACE_TSS usage.

- This fixes the infamous "ACE_Thread::setspecific() failed!: No error"
    at servers' exit on Windows builds.
This commit is contained in:
H0zen 2015-12-21 04:49:40 +02:00
parent e89cf4bc44
commit a13b03a91a
7 changed files with 62 additions and 25 deletions

View File

@ -209,6 +209,8 @@ int Master::Run()
///- Set Realm to Offline, if crash happens. Only used once.
LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%u'", REALM_FLAG_OFFLINE, realmID);
initMTRandTSS();
///- Initialize the World
sWorld.SetInitialWorldSettings();
@ -384,6 +386,8 @@ int Master::Run()
WorldDatabase.HaltDelayThread();
LoginDatabase.HaltDelayThread();
deleteMTRandTSS();
sLog.outString("Halting process...");
if (cliThread)

View File

@ -194,6 +194,7 @@ void Database::InitDelayThread()
// New delay thread for delay execute
m_threadBody = CreateDelayThread(); // will deleted at m_delayThread delete
m_TransStorage = new ACE_TSS<Database::TransHelper>();
m_delayThread = new ACE_Based::Thread(m_threadBody);
}
@ -203,9 +204,11 @@ void Database::HaltDelayThread()
m_threadBody->Stop(); // Stop event
m_delayThread->wait(); // Wait for flush to DB
delete m_TransStorage;
delete m_delayThread; // This also deletes m_threadBody
m_delayThread = NULL;
m_threadBody = NULL;
m_TransStorage=NULL;
}
void Database::ThreadStart()
@ -349,7 +352,7 @@ bool Database::Execute(const char* sql)
if (!m_pAsyncConn)
{ return false; }
SqlTransaction* pTrans = m_TransStorage->get();
SqlTransaction* pTrans = (*m_TransStorage)->get();
if (pTrans)
{
// add SQL request to trans queue
@ -415,7 +418,7 @@ bool Database::BeginTransaction()
// initiate transaction on current thread
// currently we do not support queued transactions
m_TransStorage->init();
(*m_TransStorage)->init();
return true;
}
@ -425,7 +428,7 @@ bool Database::CommitTransaction()
{ return false; }
// check if we have pending transaction
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// if async execution is not available
@ -433,7 +436,7 @@ bool Database::CommitTransaction()
{ return CommitTransactionDirect(); }
// add SqlTransaction to the async queue
m_threadBody->Delay(m_TransStorage->detach());
m_threadBody->Delay((*m_TransStorage)->detach());
return true;
}
@ -443,11 +446,11 @@ bool Database::CommitTransactionDirect()
{ return false; }
// check if we have pending transaction
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// directly execute SqlTransaction
SqlTransaction* pTrans = m_TransStorage->detach();
SqlTransaction* pTrans = (*m_TransStorage)->detach();
pTrans->Execute(m_pAsyncConn);
delete pTrans;
@ -459,11 +462,11 @@ bool Database::RollbackTransaction()
if (!m_pAsyncConn)
{ return false; }
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// remove scheduled transaction
m_TransStorage->reset();
(*m_TransStorage)->reset();
return true;
}
@ -547,7 +550,7 @@ bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)
if (!m_pAsyncConn)
{ return false; }
SqlTransaction* pTrans = m_TransStorage->get();
SqlTransaction* pTrans = (*m_TransStorage)->get();
if (pTrans)
{
// add SQL request to trans queue

View File

@ -658,7 +658,7 @@ class Database
Database() :
m_nQueryConnPoolSize(1), m_pAsyncConn(NULL), m_pResultQueue(NULL),
m_threadBody(NULL), m_delayThread(NULL), m_bAllowAsyncTransactions(false),
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0)
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0), m_TransStorage(NULL)
{
m_nQueryCounter = -1;
}
@ -737,7 +737,7 @@ class Database
*
*/
typedef ACE_TSS<Database::TransHelper> DBTransHelperTSS;
Database::DBTransHelperTSS m_TransStorage; /**< TODO */
Database::DBTransHelperTSS *m_TransStorage; /**< TODO */
///< DB connections
/**
@ -788,7 +788,7 @@ class Database
SqlResultQueue* m_pResultQueue; /**< Transaction queues from diff. threads */
SqlDelayThread* m_threadBody; /**< Pointer to delay sql executer (owned by m_delayThread) */
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
bool m_bAllowAsyncTransactions; /**< flag which specifies if async transactions are enabled */

View File

@ -131,7 +131,7 @@ Thread::~Thread()
}
// initialize Thread's class static member
Thread::ThreadStorage Thread::m_ThreadStorage;
Thread::ThreadStorage *Thread::m_ThreadStorage = NULL;
ThreadPriority Thread::m_TpEnum;
bool Thread::start()
@ -142,6 +142,8 @@ bool Thread::start()
// incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
m_task->incReference();
m_ThreadStorage = new ACE_TSS<Thread>();
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
if (res)
@ -160,6 +162,8 @@ bool Thread::wait()
m_iThreadId = 0;
m_hThreadHandle = 0;
delete m_ThreadStorage;
m_ThreadStorage = NULL;
return (_res == 0);
}
@ -174,6 +178,8 @@ void Thread::destroy()
m_iThreadId = 0;
m_hThreadHandle = 0;
delete m_ThreadStorage;
m_ThreadStorage = NULL;
// reference set at ACE_Thread::spawn
m_task->decReference();
@ -217,14 +223,14 @@ ACE_hthread_t Thread::currentHandle()
Thread* Thread::current()
{
Thread* _thread = m_ThreadStorage.ts_object();
Thread* _thread = (*m_ThreadStorage).ts_object();
if (!_thread)
{
_thread = new Thread();
_thread->m_iThreadId = Thread::currentId();
_thread->m_hThreadHandle = Thread::currentHandle();
Thread* _oldValue = m_ThreadStorage.ts_object(_thread);
Thread* _oldValue = (*m_ThreadStorage).ts_object(_thread);
delete _oldValue;
}

View File

@ -226,7 +226,7 @@ namespace ACE_Based
*
*/
typedef ACE_TSS<Thread> ThreadStorage;
static ThreadStorage m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
static ThreadStorage *m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
static ThreadPriority m_TpEnum; /**< use this object to determine current OS thread priority values mapped to enum Priority{} */
};
}

View File

@ -31,7 +31,7 @@
#include <ace/INET_Addr.h>
typedef ACE_TSS<MTRand> MTRandTSS;
static MTRandTSS mtRand;
static MTRandTSS *mtRand;
static ACE_Time_Value g_SystemTickTime = ACE_OS::gettimeofday();
@ -74,44 +74,54 @@ uint32 WorldTimer::getMSTime_internal()
}
//////////////////////////////////////////////////////////////////////////
void initMTRandTSS()
{
mtRand = new ACE_TSS<MTRand>();
}
void deleteMTRandTSS()
{
delete mtRand;
}
int32 irand(int32 min, int32 max)
{
return int32(mtRand->randInt(max - min)) + min;
return int32((*mtRand)->randInt(max - min)) + min;
}
uint32 urand(uint32 min, uint32 max)
{
return mtRand->randInt(max - min) + min;
return (*mtRand)->randInt(max - min) + min;
}
float frand(float min, float max)
{
return mtRand->randExc(max - min) + min;
return (*mtRand)->randExc(max - min) + min;
}
int32 rand32()
{
return mtRand->randInt();
return (*mtRand)->randInt();
}
double rand_norm(void)
{
return mtRand->randExc();
return (*mtRand)->randExc();
}
float rand_norm_f(void)
{
return (float)mtRand->randExc();
return (float)(*mtRand)->randExc();
}
double rand_chance(void)
{
return mtRand->randExc(100.0);
return (*mtRand)->randExc(100.0);
}
float rand_chance_f(void)
{
return (float)mtRand->randExc(100.0);
return (float)(*mtRand)->randExc(100.0);
}
Tokens StrSplit(const std::string& src, const std::string& sep)

View File

@ -106,6 +106,20 @@ inline uint32 secsToTimeBitFields(time_t secs)
return (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min;
}
/**
* @brief Initializes the TSS for MersenneTwister
*
*
*/
void initMTRandTSS();
/**
* @brief Cleanups the TSS for MersenneTwister
*
*
*/
void deleteMTRandTSS();
/**
* @brief Return a random number in the range min..max; (max-min) must be smaller than 32768.
*