mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 14:25:38 +03:00
commit for fix to a deadlock which would occur when stopping a live, queue'd thread worker
This commit is contained in:
parent
3f5bae615b
commit
2a74d2229f
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
// Module info
|
// Module info
|
||||||
#define MODULE_NAME "MySQL X"
|
#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_AUTHOR "AMX Mod X Dev Team"
|
||||||
#define MODULE_URL "http://www.amxmodx.org/"
|
#define MODULE_URL "http://www.amxmodx.org/"
|
||||||
#define MODULE_LOGTAG "SQLX"
|
#define MODULE_LOGTAG "SQLX"
|
||||||
|
@ -46,7 +46,7 @@ void ThreadWorker::OnTerminate(IThreadHandle *pHandle, bool cancel)
|
|||||||
|
|
||||||
void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
||||||
{
|
{
|
||||||
WorkerState this_state;
|
WorkerState this_state = Worker_Running;
|
||||||
size_t num;
|
size_t num;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -54,6 +54,8 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
|||||||
/**
|
/**
|
||||||
* Check number of items in the queue
|
* Check number of items in the queue
|
||||||
*/
|
*/
|
||||||
|
if (this_state != Worker_Stopped)
|
||||||
|
{
|
||||||
m_QueueLock->Lock();
|
m_QueueLock->Lock();
|
||||||
num = m_ThreadQueue.size();
|
num = m_ThreadQueue.size();
|
||||||
if (!num)
|
if (!num)
|
||||||
@ -68,19 +70,21 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
|||||||
} else {
|
} else {
|
||||||
m_QueueLock->Unlock();
|
m_QueueLock->Unlock();
|
||||||
}
|
}
|
||||||
/**
|
}
|
||||||
* Pause in the case of .. pausing!
|
|
||||||
*/
|
|
||||||
m_StateLock->Lock();
|
m_StateLock->Lock();
|
||||||
this_state = m_state;
|
this_state = m_state;
|
||||||
m_StateLock->Unlock();
|
m_StateLock->Unlock();
|
||||||
if (this_state != Worker_Running)
|
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 (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.
|
// run all of the remaining frames first.
|
||||||
// also, don't sleep.
|
|
||||||
if (!m_FlushType)
|
if (!m_FlushType)
|
||||||
{
|
{
|
||||||
while (m_ThreadQueue.size())
|
while (m_ThreadQueue.size())
|
||||||
@ -88,10 +92,6 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
|
|||||||
}
|
}
|
||||||
break;
|
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)
|
if (m_state == Worker_Invalid || m_state == Worker_Stopped)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_state == Worker_Paused)
|
WorkerState oldstate;
|
||||||
{
|
|
||||||
if (!Unpause())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set new state
|
//set new state
|
||||||
m_StateLock->Lock();
|
m_StateLock->Lock();
|
||||||
|
oldstate = m_state;
|
||||||
m_state = Worker_Stopped;
|
m_state = Worker_Stopped;
|
||||||
|
m_FlushType = flush_cancel;
|
||||||
m_StateLock->Unlock();
|
m_StateLock->Unlock();
|
||||||
|
|
||||||
m_FlushType = flush_cancel;
|
if (oldstate == Worker_Paused)
|
||||||
|
|
||||||
//wait for thread to catch up
|
|
||||||
if (m_Waiting)
|
|
||||||
{
|
{
|
||||||
|
Unpause();
|
||||||
|
} else {
|
||||||
m_AddSignal->Signal();
|
m_AddSignal->Signal();
|
||||||
|
Pause();
|
||||||
|
Unpause();
|
||||||
}
|
}
|
||||||
|
|
||||||
me->WaitForThread();
|
me->WaitForThread();
|
||||||
//destroy it
|
//destroy it
|
||||||
me->DestroyThis();
|
me->DestroyThis();
|
||||||
|
@ -33,8 +33,8 @@ protected:
|
|||||||
IEventSignal *m_AddSignal;
|
IEventSignal *m_AddSignal;
|
||||||
IThreadHandle *me;
|
IThreadHandle *me;
|
||||||
unsigned int m_think_time;
|
unsigned int m_think_time;
|
||||||
bool m_Waiting;
|
volatile bool m_Waiting;
|
||||||
bool m_FlushType;
|
volatile bool m_FlushType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_THREADWORKER_H
|
#endif //_INCLUDE_SOURCEMOD_THREADWORKER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user