Dead lock sometimes happens, I guess it is in CC.
I try to find some pattern which are the answers describe in
What are common reasons for deadlocks?void cbThreadPool::AddTask(cbThreadedTask *task, bool autodelete)
{
if (!task)
return;
wxMutexLocker lock(m_Mutex);
m_tasksQueue.push_back(cbThreadedTaskElement(task, autodelete));
m_taskAdded = true;
// we are in batch mode, so no need to awake the idle thread
// m_workingThreads < m_concurrentThreads means there are some threads in idle mode (no task assigned)
if (!m_batching && m_workingThreads < m_concurrentThreads)
AwakeNeeded();
}
In main thread:In void Parser::OnBatchTimer(cb_unused wxTimerEvent& event)
bool send_event = true;
bool sendStartParseEvent = false;
if ( !m_BatchParseFiles.empty()
|| !m_PredefinedMacros.IsEmpty() )
{
CC_LOCKER_TRACK_P_MTX_LOCK(ParserCommon::s_ParserMutex)
ParserThreadedTask* thread = new ParserThreadedTask(this, ParserCommon::s_ParserMutex);
TRACE(_T("Parser::OnBatchTimer(): Adding a ParserThreadedTask thread to m_Pool."));
m_Pool.AddTask(thread, true); //once this function is called, the thread will be executed from the pool.
if (ParserCommon::s_CurrentParser)
send_event = false;
else // Have not done any batch parsing yet -> assign parser
{
ParserCommon::s_CurrentParser = this;
m_StopWatch.Start(); // reset timer
sendStartParseEvent = true;
}
CC_LOCKER_TRACK_P_MTX_UNLOCK(ParserCommon::s_ParserMutex)
}
Or
bool Parser::Done()
{
CC_LOCKER_TRACK_P_MTX_LOCK(ParserCommon::s_ParserMutex)
bool done = m_BatchParseFiles.empty()
&& m_PredefinedMacros.IsEmpty()
&& !m_NeedMarkFileAsLocal
&& m_Pool.Done();
CC_LOCKER_TRACK_P_MTX_UNLOCK(ParserCommon::s_ParserMutex)
return done;
}
In worker thread:int ParserThreadedTask::Execute()
CC_LOCKER_TRACK_P_MTX_UNLOCK(m_ParserMutex);
if (m_Parser->m_IgnoreThreadEvents)
m_Parser->m_IsFirstBatch = true;
TRACE(_T("ParserThreadedTask::Execute(): Parse source files"));
while (!batchFiles.empty())
{
TRACE(_T("-ParserThreadedTask::Execute(): Parse %s"), batchFiles.front().wx_str());
m_Parser->Parse(batchFiles.front()); // bool isLocal = true, bool locked = false
batchFiles.pop_front();
}
CC_LOCKER_TRACK_P_MTX_LOCK(m_ParserMutex)
All the patterns are:
lock the parser mutex
lock the pool
release the pool
release the parser mutex
Is it the bad code pattern which may cause dead lock?
EDIT: It looks like the answer is NO.