Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => CodeCompletion redesign => Topic started by: ollydbg on October 01, 2014, 12:53:21 PM

Title: potential dead lock pattern in CC?
Post by: ollydbg on October 01, 2014, 12:53:21 PM
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? (http://stackoverflow.com/a/528362/154911)


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. ;)