1
0

Fixed *nix threading issue;

Thread objects now use variable names consistent with MCS convention;
Fixed a few *nix threading cornercases

git-svn-id: http://mc-server.googlecode.com/svn/trunk@392 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-03-10 17:37:00 +00:00
parent e5b91a8d97
commit 1a5ebb44aa
11 changed files with 93 additions and 88 deletions

View File

@ -30,7 +30,7 @@ cChunkSender::cChunkSender(void) :
cChunkSender::~cChunkSender()
{
mShouldTerminate = true;
m_ShouldTerminate = true;
m_evtQueue.Set();
}
@ -100,7 +100,7 @@ void cChunkSender::RemoveClient(cClientHandle * a_Client)
void cChunkSender::Execute(void)
{
while (!mShouldTerminate)
while (!m_ShouldTerminate)
{
cCSLock Lock(m_CS);
while (m_ChunksReady.empty() && m_SendChunks.empty())
@ -108,7 +108,7 @@ void cChunkSender::Execute(void)
cCSUnlock Unlock(Lock);
m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted
m_evtQueue.Wait();
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}

View File

@ -40,7 +40,7 @@ void cLightingThread::Stop(void)
delete *itr;
} // for itr - m_Queue[]
}
mShouldTerminate = true;
m_ShouldTerminate = true;
m_Event.Set();
Wait();

View File

@ -153,10 +153,11 @@ void cWorldStorage::WaitForFinish(void)
}
// Wait for the thread to finish:
mShouldTerminate = true;
m_ShouldTerminate = true;
m_Event.Set();
m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method
super::Wait();
LOG("World storage thread finished");
}
@ -166,7 +167,7 @@ void cWorldStorage::WaitForFinish(void)
void cWorldStorage::WaitForQueuesEmpty(void)
{
cCSLock Lock(m_CSQueues);
while (!mShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty()))
while (!m_ShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty()))
{
cCSUnlock Unlock(Lock);
m_evtRemoved.Wait();
@ -305,7 +306,7 @@ void cWorldStorage::InitSchemas(void)
void cWorldStorage::Execute(void)
{
while (!mShouldTerminate)
while (!m_ShouldTerminate)
{
m_Event.Wait();
@ -314,7 +315,7 @@ void cWorldStorage::Execute(void)
do
{
HasMore = false;
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}

View File

@ -24,9 +24,9 @@
cAuthenticator::cAuthenticator(void) :
super("cAuthenticator"),
mServer(DEFAULT_AUTH_SERVER),
mAddress(DEFAULT_AUTH_ADDRESS),
mShouldAuthenticate(true)
m_Server(DEFAULT_AUTH_SERVER),
m_Address(DEFAULT_AUTH_ADDRESS),
m_ShouldAuthenticate(true)
{
ReadINI();
}
@ -53,27 +53,27 @@ void cAuthenticator::ReadINI(void)
return;
}
mServer = IniFile.GetValue("Authentication", "Server");
mAddress = IniFile.GetValue("Authentication", "Address");
mShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true);
m_Server = IniFile.GetValue("Authentication", "Server");
m_Address = IniFile.GetValue("Authentication", "Address");
m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true);
bool bSave = false;
if (mServer.length() == 0)
if (m_Server.length() == 0)
{
mServer = DEFAULT_AUTH_SERVER;
IniFile.SetValue("Authentication", "Server", mServer);
m_Server = DEFAULT_AUTH_SERVER;
IniFile.SetValue("Authentication", "Server", m_Server);
bSave = true;
}
if (mAddress.length() == 0)
if (m_Address.length() == 0)
{
mAddress = DEFAULT_AUTH_ADDRESS;
IniFile.SetValue("Authentication", "Address", mAddress);
m_Address = DEFAULT_AUTH_ADDRESS;
IniFile.SetValue("Authentication", "Address", m_Address);
bSave = true;
}
if (bSave)
{
IniFile.SetValueB("Authentication", "Authenticate", mShouldAuthenticate);
IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate);
IniFile.WriteFile();
}
}
@ -85,15 +85,15 @@ void cAuthenticator::ReadINI(void)
/// Queues a request for authenticating a user. If the auth fails, the user is kicked
void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
{
if (!mShouldAuthenticate)
if (!m_ShouldAuthenticate)
{
cRoot::Get()->AuthenticateUser(a_ClientID);
return;
}
cCSLock Lock(mCS);
mQueue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
mQueueNonempty.Set();
cCSLock Lock(m_CS);
m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
m_QueueNonempty.Set();
}
@ -102,8 +102,8 @@ void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, co
void cAuthenticator::Stop(void)
{
mShouldTerminate = true;
mQueueNonempty.Set();
m_ShouldTerminate = true;
m_QueueNonempty.Set();
Wait();
}
@ -115,27 +115,27 @@ void cAuthenticator::Execute(void)
{
for (;;)
{
cCSLock Lock(mCS);
while (!mShouldTerminate && (mQueue.size() == 0))
cCSLock Lock(m_CS);
while (!m_ShouldTerminate && (m_Queue.size() == 0))
{
cCSUnlock Unlock(Lock);
mQueueNonempty.Wait();
m_QueueNonempty.Wait();
}
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}
ASSERT(mQueue.size() > 0);
ASSERT(m_Queue.size() > 0);
int ClientID = mQueue.front().mClientID;
AString UserName = mQueue.front().mName;
AString ActualAddress = mAddress;
int ClientID = m_Queue.front().mClientID;
AString UserName = m_Queue.front().mName;
AString ActualAddress = m_Address;
ReplaceString(ActualAddress, "%USERNAME%", UserName);
ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID());
mQueue.pop_front();
m_Queue.pop_front();
Lock.Unlock();
if (!AuthFromAddress(mServer, ActualAddress, UserName))
if (!AuthFromAddress(m_Server, ActualAddress, UserName))
{
cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
}

View File

@ -59,13 +59,13 @@ private:
typedef std::deque<cUser> cUserList;
cCriticalSection mCS;
cUserList mQueue;
cEvent mQueueNonempty;
cCriticalSection m_CS;
cUserList m_Queue;
cEvent m_QueueNonempty;
AString mServer;
AString mAddress;
bool mShouldAuthenticate;
AString m_Server;
AString m_Address;
bool m_ShouldAuthenticate;
// cIsThread override:
virtual void Execute(void) override;

View File

@ -69,7 +69,7 @@ bool cChunkGenerator::Start(cWorld * a_World, const AString & a_WorldGeneratorNa
void cChunkGenerator::Stop(void)
{
mShouldTerminate = true;
m_ShouldTerminate = true;
m_Event.Set();
m_evtRemoved.Set(); // Wake up anybody waiting for empty queue
Wait();
@ -115,7 +115,7 @@ void cChunkGenerator::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
void cChunkGenerator::WaitForQueueEmpty(void)
{
cCSLock Lock(m_CS);
while (!mShouldTerminate && !m_Queue.empty())
while (!m_ShouldTerminate && !m_Queue.empty())
{
cCSUnlock Unlock(Lock);
m_evtRemoved.Wait();
@ -138,14 +138,14 @@ int cChunkGenerator::GetQueueLength(void)
void cChunkGenerator::Execute(void)
{
while (!mShouldTerminate)
while (!m_ShouldTerminate)
{
cCSLock Lock(m_CS);
while (m_Queue.size() == 0)
{
cCSUnlock Unlock(Lock);
m_Event.Wait();
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}

View File

@ -51,12 +51,12 @@ static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName)
// cIsThread:
cIsThread::cIsThread(const AString & iThreadName) :
mThreadName(iThreadName),
mShouldTerminate(false),
m_ThreadName(iThreadName),
m_ShouldTerminate(false),
#ifdef _WIN32
mHandle(NULL)
m_Handle(NULL)
#else // _WIN32
mHasStarted(false)
m_HasStarted(false)
#endif // else _WIN32
{
}
@ -67,7 +67,7 @@ cIsThread::cIsThread(const AString & iThreadName) :
cIsThread::~cIsThread()
{
mShouldTerminate = true;
m_ShouldTerminate = true;
Wait();
}
@ -78,34 +78,35 @@ cIsThread::~cIsThread()
bool cIsThread::Start(void)
{
#ifdef _WIN32
ASSERT(mHandle == NULL); // Has already started one thread?
ASSERT(m_Handle == NULL); // Has already started one thread?
// Create the thread suspended, so that the mHandle variable is valid in the thread procedure
DWORD ThreadID = 0;
mHandle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID);
if (mHandle == NULL)
m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID);
if (m_Handle == NULL)
{
LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", mThreadName.c_str(), GetLastError());
LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError());
return false;
}
ResumeThread(mHandle);
ResumeThread(m_Handle);
#if defined(_DEBUG) && defined(_MSC_VER)
// Thread naming is available only in MSVC
if (!mThreadName.empty())
if (!m_ThreadName.empty())
{
SetThreadName(ThreadID, mThreadName.c_str());
SetThreadName(ThreadID, m_ThreadName.c_str());
}
#endif // _DEBUG and _MSC_VER
#else // _WIN32
ASSERT(!mHasStarted);
ASSERT(!m_HasStarted);
if (pthread_create(&mHandle, NULL, thrExecute, this))
if (pthread_create(&m_Handle, NULL, thrExecute, this))
{
LOGERROR("ERROR: Could not create thread \"%s\", !", mThreadName.c_str());
LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str());
return false;
}
m_HasStarted = true;
#endif // else _WIN32
return true;
@ -119,28 +120,30 @@ bool cIsThread::Wait(void)
{
#ifdef _WIN32
if (mHandle == NULL)
if (m_Handle == NULL)
{
return true;
}
// Cannot log, logger may already be stopped:
// LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str());
int res = WaitForSingleObject(mHandle, INFINITE);
mHandle = NULL;
// LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str());
int res = WaitForSingleObject(m_Handle, INFINITE);
m_Handle = NULL;
// Cannot log, logger may already be stopped:
// LOG("Thread \"%s\" %s terminated, GLE = %d", mThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError());
// LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError());
return (res == WAIT_OBJECT_0);
#else // _WIN32
if (!mHasStarted)
if (!m_HasStarted)
{
return true;
}
LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str());
int res = pthread_join(mHandle, NULL);
mHasStarted = false;
LOG("Thread \"%s\" %s terminated, errno = %d", mThreadName.c_str(), (res == 0) ? "" : "not", errno);
// Cannot log, logger may already be stopped:
// LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str());
int res = pthread_join(m_Handle, NULL);
m_HasStarted = false;
// Cannot log, logger may already be stopped:
// LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno);
return (res == 0);
#endif // else _WIN32

View File

@ -28,7 +28,7 @@ class cIsThread
protected:
virtual void Execute(void) = 0; // This function is called in the new thread's context
volatile bool mShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true
volatile bool m_ShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true
public:
cIsThread(const AString & iThreadName);
@ -40,26 +40,26 @@ public:
static unsigned long GetCurrentID(void); // Returns the OS-dependent thread ID for the caller's thread
private:
AString mThreadName;
AString m_ThreadName;
#ifdef _WIN32
HANDLE mHandle;
HANDLE m_Handle;
static DWORD_PTR __stdcall thrExecute(LPVOID iParam)
static DWORD_PTR __stdcall thrExecute(LPVOID a_Param)
{
((cIsThread *)iParam)->Execute();
((cIsThread *)a_Param)->Execute();
return 0;
}
#else // _WIN32
pthread_t mHandle;
bool mHasStarted;
pthread_t m_Handle;
bool m_HasStarted;
static void * thrExecute(void * iParam)
static void * thrExecute(void * a_Param)
{
((cIsThread *)iParam)->Execute();
((cIsThread *)a_Param)->Execute();
return NULL;
}

View File

@ -666,7 +666,7 @@ cServer::cNotifyWriteThread::cNotifyWriteThread(void) :
cServer::cNotifyWriteThread::~cNotifyWriteThread()
{
mShouldTerminate = true;
m_ShouldTerminate = true;
m_Event.Set();
Wait();
}
@ -688,14 +688,14 @@ bool cServer::cNotifyWriteThread::Start(cServer * a_Server)
void cServer::cNotifyWriteThread::Execute(void)
{
cClientHandleList Clients;
while (!mShouldTerminate)
while (!m_ShouldTerminate)
{
cCSLock Lock(m_CS);
while (m_Clients.size() == 0)
{
cCSUnlock Unlock(Lock);
m_Event.Wait();
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}

View File

@ -155,7 +155,8 @@ void cSocketThreads::Write(const cSocket * a_Socket, const AString & a_Data)
}
} // for itr - m_Threads[]
ASSERT(!"Writing to an unknown socket");
// This may be perfectly legal, if the socket has been destroyed and the client is finishing up
// ASSERT(!"Writing to an unknown socket");
}
@ -224,7 +225,7 @@ cSocketThreads::cSocketThread::cSocketThread(cSocketThreads * a_Parent) :
cSocketThreads::cSocketThread::~cSocketThread()
{
mShouldTerminate = true;
m_ShouldTerminate = true;
m_ControlSocket1.CloseSocket();
m_ControlSocket2.CloseSocket();
}
@ -506,7 +507,7 @@ void cSocketThreads::cSocketThread::Execute(void)
}
// The main thread loop:
while (!mShouldTerminate)
while (!m_ShouldTerminate)
{
// Put all sockets into the Read set:
fd_set fdRead;

View File

@ -113,7 +113,7 @@ protected:
for (int i = 0; i < 20; i++)
{
cSleep::MilliSleep(100);
if (mShouldTerminate)
if (m_ShouldTerminate)
{
return;
}