[8328] Fixed problem with crash at startup in result destroy anti-freeze thread runnable.

* Destroy runnable only if no references.
* Some code cleanups
This commit is contained in:
VladimirMangos 2009-08-08 09:35:59 +04:00
parent 79c1324bed
commit 7baebcd2de
5 changed files with 50 additions and 18 deletions

View file

@ -223,8 +223,8 @@ int Master::Run()
_HookSignals(); _HookSignals();
///- Launch WorldRunnable thread ///- Launch WorldRunnable thread
ACE_Based::Thread t(new WorldRunnable); ACE_Based::Thread world_thread(new WorldRunnable);
t.setPriority(ACE_Based::Highest); world_thread.setPriority(ACE_Based::Highest);
// set server online // set server online
loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID);
@ -241,7 +241,7 @@ int Master::Run()
cliThread = new ACE_Based::Thread(new CliRunnable); cliThread = new ACE_Based::Thread(new CliRunnable);
} }
ACE_Based::Thread td2(new RARunnable); ACE_Based::Thread rar_thread(new RARunnable);
///- Handle affinity for multiple processors and process priority on Windows ///- Handle affinity for multiple processors and process priority on Windows
#ifdef WIN32 #ifdef WIN32
@ -297,13 +297,12 @@ int Master::Run()
uint32 loopCounter = 0; uint32 loopCounter = 0;
///- Start up freeze catcher thread ///- Start up freeze catcher thread
uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0); if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0))
if(freeze_delay)
{ {
FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable();
fdr->SetDelayTime(freeze_delay*1000); fdr->SetDelayTime(freeze_delay*1000);
ACE_Based::Thread t(fdr); ACE_Based::Thread freeze_thread(fdr);
t.setPriority(ACE_Based::Highest); freeze_thread.setPriority(ACE_Based::Highest);
} }
///- Launch the world listener socket ///- Launch the world listener socket
@ -327,8 +326,8 @@ int Master::Run()
// when the main thread closes the singletons get unloaded // when the main thread closes the singletons get unloaded
// since worldrunnable uses them, it will crash if unloaded after master // since worldrunnable uses them, it will crash if unloaded after master
t.wait(); world_thread.wait();
td2.wait (); rar_thread.wait ();
///- Clean database before leaving ///- Clean database before leaving
clearOnlineAccounts(); clearOnlineAccounts();
@ -340,7 +339,7 @@ int Master::Run()
sLog.outString( "Halting process..." ); sLog.outString( "Halting process..." );
if(cliThread) if (cliThread)
{ {
#ifdef WIN32 #ifdef WIN32

View file

@ -58,7 +58,7 @@ class AuthSocket: public TcpSocket
void _SetVSFields(const std::string& rI); void _SetVSFields(const std::string& rI);
FILE *pPatch; FILE *pPatch;
ACE_Thread_Mutex patcherLock; ACE_Thread_Mutex patcherLock;
bool IsLag(); bool IsLag();
private: private:

View file

@ -103,6 +103,10 @@ Thread::Thread() : m_task(0), m_iThreadId(0), m_hThreadHandle(0)
Thread::Thread(Runnable* instance) : m_task(instance), m_iThreadId(0), m_hThreadHandle(0) Thread::Thread(Runnable* instance) : m_task(instance), m_iThreadId(0), m_hThreadHandle(0)
{ {
// register reference to m_task to prevent it deeltion until destructor
if (m_task)
m_task->incReference();
bool _start = start(); bool _start = start();
ASSERT (_start); ASSERT (_start);
} }
@ -111,8 +115,9 @@ Thread::~Thread()
{ {
//Wait(); //Wait();
// deleted runnable object (owned by Thread) // deleted runnable object (if no other references)
delete m_task; if (m_task)
m_task->decReference();
} }
//initialize Thread's class static member //initialize Thread's class static member
@ -121,15 +126,20 @@ ThreadPriority Thread::m_TpEnum;
bool Thread::start() bool Thread::start()
{ {
if(m_task == 0 || m_iThreadId != 0) if (m_task == 0 || m_iThreadId != 0)
return false; return false;
return (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0); bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
if (res)
m_task->incReference();
return res;
} }
bool Thread::wait() bool Thread::wait()
{ {
if(!m_hThreadHandle || !m_task) if (!m_hThreadHandle || !m_task)
return false; return false;
ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1); ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1);
@ -143,7 +153,17 @@ bool Thread::wait()
void Thread::destroy() void Thread::destroy()
{ {
ACE_Thread::kill(m_iThreadId, -1); if (!m_iThreadId || !m_task)
return;
if (ACE_Thread::kill(m_iThreadId, -1) != 0)
return;
m_iThreadId = 0;
m_hThreadHandle = 0;
// reference set at ACE_Thread::spawn
m_task->decReference();
} }
void Thread::suspend() void Thread::suspend()
@ -161,6 +181,9 @@ ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
Runnable * _task = (Runnable*)param; Runnable * _task = (Runnable*)param;
_task->run(); _task->run();
// task execution complete, free referecne added at
_task->decReference();
return (ACE_THR_FUNC_RETURN)0; return (ACE_THR_FUNC_RETURN)0;
} }

View file

@ -21,6 +21,7 @@
#include <ace/Thread.h> #include <ace/Thread.h>
#include <ace/TSS_T.h> #include <ace/TSS_T.h>
#include "ace/Atomic_Op.h"
#include <assert.h> #include <assert.h>
#include "Errors.h" #include "Errors.h"
@ -32,6 +33,15 @@ namespace ACE_Based
public: public:
virtual ~Runnable() {} virtual ~Runnable() {}
virtual void run() = 0; virtual void run() = 0;
void incReference() { ++m_refs; }
void decReference()
{
if(!--m_refs)
delete this;
}
private:
ACE_Atomic_Op<ACE_Thread_Mutex, int> m_refs;
}; };
enum Priority enum Priority

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8327" #define REVISION_NR "8328"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__