commit for fix to a deadlock which would occur when stopping a live, queue'd thread worker

This commit is contained in:
David Anderson 2006-04-25 20:41:18 +00:00
parent 3f5bae615b
commit 2a74d2229f
3 changed files with 42 additions and 42 deletions

View File

@ -5,7 +5,7 @@
// Module info
#define MODULE_NAME "MySQL X"
#define MODULE_VERSION "1.00"
#define MODULE_VERSION "1.01"
#define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org/"
#define MODULE_LOGTAG "SQLX"

View File

@ -46,7 +46,7 @@ void ThreadWorker::OnTerminate(IThreadHandle *pHandle, bool cancel)
void ThreadWorker::RunThread(IThreadHandle *pHandle)
{
WorkerState this_state;
WorkerState this_state = Worker_Running;
size_t num;
while (true)
@ -54,6 +54,8 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
/**
* Check number of items in the queue
*/
if (this_state != Worker_Stopped)
{
m_QueueLock->Lock();
num = m_ThreadQueue.size();
if (!num)
@ -68,19 +70,21 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
} else {
m_QueueLock->Unlock();
}
/**
* Pause in the case of .. pausing!
*/
}
m_StateLock->Lock();
this_state = m_state;
m_StateLock->Unlock();
if (this_state != Worker_Running)
{
if (this_state == Worker_Paused || this_state == Worker_Stopped)
{
//wait until the lock is cleared.
if (this_state == Worker_Paused)
m_PauseSignal->Wait();
if (this_state == Worker_Stopped)
{
//if we're supposed to flush cleanly,
//if we're supposed to flush cleanrly,
// run all of the remaining frames first.
// also, don't sleep.
if (!m_FlushType)
{
while (m_ThreadQueue.size())
@ -88,10 +92,6 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
}
break;
}
if (this_state == Worker_Paused)
{
//wait until the lock is cleared.
m_PauseSignal->Wait();
}
}
/**
@ -174,24 +174,24 @@ bool ThreadWorker::Stop(bool flush_cancel)
if (m_state == Worker_Invalid || m_state == Worker_Stopped)
return false;
if (m_state == Worker_Paused)
{
if (!Unpause())
return false;
}
WorkerState oldstate;
//set new state
m_StateLock->Lock();
oldstate = m_state;
m_state = Worker_Stopped;
m_FlushType = flush_cancel;
m_StateLock->Unlock();
m_FlushType = flush_cancel;
//wait for thread to catch up
if (m_Waiting)
if (oldstate == Worker_Paused)
{
Unpause();
} else {
m_AddSignal->Signal();
Pause();
Unpause();
}
me->WaitForThread();
//destroy it
me->DestroyThis();

View File

@ -33,8 +33,8 @@ protected:
IEventSignal *m_AddSignal;
IThreadHandle *me;
unsigned int m_think_time;
bool m_Waiting;
bool m_FlushType;
volatile bool m_Waiting;
volatile bool m_FlushType;
};
#endif //_INCLUDE_SOURCEMOD_THREADWORKER_H